Angular Material 2(MatDatepickerModule) - 日期选择器中选择的日期为1天

时间:2017-09-26 20:24:09

标签: javascript angular typescript datepicker angular-material2

我正在使用Angular Material Beta 11版本的Angular应用程序(v4.4.3)。对于beta 11,datepicker接受ISOformat字符串中的日期。但是,在我的应用中,日期选择器模块中的日期关闭1天,如下图所示:

enter image description here

我的应用程序中的日期流程如下,应用程序从Mysql数据库接收Unix Epoch时间的日期,并将该Epoch时间日期转换为ISOString字符串格式,并将该ISO日期返回到matDatePicker。

/**
 * This method takes the key, which is a epoch time in string format and convert into JS Date object.
 * @param key {string} - the epoch time
 * @return {string} - Date Object.
 */
private static dateHelper(key: string): any {
    const dateObj = new Date(+key * 1000);
    // Need to return ISOString format date as accepted by Material DatePicker component
    return dateObj.toISOString().substring(0, 10);

}

我还有日期选择器模块,以自定义格式显示日期:

import {NgModule} from '@angular/core';
import {MdDatepickerModule, MdNativeDateModule, NativeDateAdapter, DateAdapter, MD_DATE_FORMATS} from '@angular/material';

// extend NativeDateAdapter's format method to specify the date format.
export class CustomDateAdapter extends NativeDateAdapter {
    format(date: Date, displayFormat: Object): string {
        if (displayFormat === 'input') {
            const day = date.getUTCDate();
            const month = date.getUTCMonth() + 1;
            const year = date.getFullYear();
            return `${year}-${month}-${day}`;
        } else {
            return date.toDateString();
        }
    }
}

const MY_DATE_FORMATS = {
    parse: {
        dateInput: {month: 'short', year: 'numeric', day: 'numeric'}
    },
    display: {
        dateInput: 'input',
        monthYearLabel: {year: 'numeric', month: 'short'},
        dateA11yLabel: {year: 'numeric', month: 'long', day: 'numeric'},
        monthYearA11yLabel: {year: 'numeric', month: 'long'},
    }
};

@NgModule({
    declarations: [],
    imports: [],
    exports: [MdDatepickerModule, MdNativeDateModule],
    providers: [
        {
            provide: DateAdapter, useClass: CustomDateAdapter
        },
        {
            provide: MD_DATE_FORMATS, useValue: MY_DATE_FORMATS
        }
    ]
})

export class DatePickerModule {

}

DatePicker:

    <mat-form-field>
            <input matInput
                   [matDatepicker]="myDate"
                   placeholder="Start Date"                       
                   [(ngModel)]="date"
                   name="start_date" required>
            <mat-datepicker-toggle matSuffix [for]="myDate"></mat-datepicker-toggle>
            <mat-datepicker #myDate></mat-datepicker>
            <mat-error>This field is required!</mat-error>
        </mat-form-field>

我对谷歌做过关于它的事情,并且有一些关于此问题的帖子,但我无法完全关注它们。任何意见的输入将受到高度赞赏。谢谢!

4 个答案:

答案 0 :(得分:1)

如果您在date.getDate()方法中使用date.getMonth()date.getUTCDate()不是 date.getUTCMonth()format,那么它应该有效您的自定义日期适配器。

尝试告诉我们:

export class CustomDateAdapter extends NativeDateAdapter {
    format(date: Date, displayFormat: Object): string {
           if (displayFormat == "input") {
               let day = date.getDate();
               let month = date.getMonth() + 1;
               let year = date.getFullYear();
               return `${year}-${month}-${day}`
           } else {
               return date.toDateString();
           }
       }
}

答案 1 :(得分:1)

得到了解决。感谢大家的投入。

所以在这里进行一些讨论并浏览Angular Material 2 Github问题和帖子后,我得到了一些想法和方法来将Date分配给DatePicker组件。使用Material beta 11,DatePicker组件可以将日期设置为DateISOString格式。当我使用ISOString格式时,我遇到了问题。我刚刚将其更新为正常Date格式,如下所示。

我的问题更新的代码片段:

 /**
 * This method takes the key, which is a epoch time in string format and 
 * convert into JS Date object.
 * @param key {string} - the epoch time
 * @return {string} - Date Object.
 */
private static dateHelper(key: string): any {
    const dateObj = new Date(+key * 1000);
    // Need to return Date object/ISOString format date as accepted by Material DatePicker component
    return new Date(dateObj.getFullYear(), dateObj.getUTCMonth(), dateObj.getUTCDate());;

}

这是我为匹配mdInput和日历中的日期所做的唯一更改。当我使用ISOString格式时,我仍然不确定问题的原因。此外,我意识到我不需要使用任何CustomDateAdapter,因为它主要用于外观目的。

答案 2 :(得分:0)

在控制台中进行调试时,某个日期最有可能以时区表示。表示的时区与UTC之间的差异为1天。

可能是date.toDataString()。

请参阅this

答案 3 :(得分:0)

我对此并不十分清楚,但我怀疑是Date转换的时间段和时区对它的影响。尝试使用this方法转换数据库时间。

最有可能在这一行,

const dateObj = new Date(+key * 1000);

Date构造函数可能会根据您的本地(系统)TZ初始化日期,这可能会使UTC时间偏移。

修改

好的,深入挖掘一下。我想我已经把球停在了这个问题的原因上。您可能必须在parse()中自定义CustomDateAdapter方法,因为它实际将给定的date(UTC)转换为本地时间(区域)日期的parse()内置parse(value: any): Date | null { if (typeof value == 'number') { return new Date(value); // not likely to enter here as your date is in 'string' format } return value ? new Date(Date.parse(value + ' GMT')) : null; //forces Time Zone to GMT/UTC and converts it } 方法。

尝试在CustomDateAdapter

中添加一些效果
commonPrefix("", "something"), //one string is ""
commonPrefix("some", "something"), " //for loop finishes
commonPrefix("someother", "something") //for loop breaks

看看它是否解决了您的问题。