angular - 日期是前一天
问题描述
我在我的日期选择器中选择日期May 01 1985并发dateOfBirth.value
送到我的服务器,以便它可以存储在数据库中。
<mat-form-field>
<label><input #dateOfBirth matInput (blur)="_update('personal', 'dateOfBirth', dateOfBirth.value)" (click)="picker.open()" [matDatepicker]="picker" placeholder="Choose a date" formControlName="dateOfBirth" autocomplete="off" [max]="maxDate" [min]="minDate"></label>
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker touchUi #picker startView="multi-year"></mat-datepicker>
<mat-error *ngIf="profileFormGroup.get('dateOfBirth').errors">Date is not valid</mat-error>
</mat-form-field>
每当我刷新页面时,所选日期应该仍然可见。
我的问题是,我选择了日期05/01/1985,但我的日期选择器显示了4/30/1985。为什么?
private static _formatDate(timestamp: number): string {
console.log(timestamp); // Returns 483746400000
const date = new Date(+timestamp);
console.log(date.getDay()); // Returns 3 but it should be 1
return date.toISOString().substring(0, 10);
}
ngOnInit() {
this.profileService.getEntities().subscribe(data => {
this.profileFormGroup.get('dateOfBirth').patchValue(ProfileComponent._formatDate(data.dateOfBirth));
});
}
这是我在数据库中存储时间戳的方式:
private _update(tableName: string, columnName: string, theValue: any) {
// Set the correct value of dateOfBirth
console.log(theValue); // Returns 5/1/1985
if (columnName === 'dateOfBirth') {
const splitDate = theValue.split('/');
const newDate = `${splitDate[2]}/${splitDate[0]}/${splitDate[1]}`;
theValue = new Date(newDate).getTime();
console.log(theValue); // Returns 483746400000
}
const json = {
table: tableName,
column: columnName,
value: theValue
};
this.profileService.update(json).subscribe(result => {
console.log(result);
});
}
我还在Stackblitz 上检查了类似这样的其他示例。如果选择日期01/05/2020 ,输出将是2020-04-30T22 :00:00.000Z,这是错误的。
解决方案
根据您所在的地区,五月属于夏令时。
设置 1985 年 5 月 1 日的日期应该就像1985-05-01T00:00.000+1:00
您保留时区一样。
看起来正在发生的是您正在以 UTC 格式提取日期。这会将日期转换为 +0:00,从而将您带到前一天的1985-04-30T23:00.000+0.00
.
如果您尝试 Stackblitz,问题就得到了证明 - 选择 3 月底之前和 10 月底之后的日期 - 这些日期可以正常工作,因为它们不是夏令时。
您的格式日期函数使用.toISOString()
. 根据 Mozzila (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString),这将始终返回 UTC 时间,并且您的日期会晚一小时,因此时值午夜,倒到前一天。
由于您只关心日期,并且日期选择器可能会以每种方式抵消最多 12 小时,我们可以检查这一点。
默认日期始终为午夜,因此在 UTC 之前的任何时间都可以,因为它将保持相同的日期。任何落后于 UTC 的时间都可以追溯到 12 小时,并一直持续到第二天。
在代码中,检查时区偏移会告诉我们是否落后。如果是这样,那么我们希望将小时数添加到 datetime 对象中,以便在使用时toISOString
我们仍然可以选择日期。
所以函数应该如下:
const date = new Date(+timestamp);
const offset = date.getTimezoneOffset();
if (offset < 0) {
date.setHours(12,0,0);
}
return date.toISOString().substring(0,10);
推荐阅读
- ruby-on-rails - Rails:如何访问 lib 文件夹类中的“请求”?
- r - 尝试从 Microsoft Store 加载 Office 中的 R.dll 时,VBA 中的 LoadLibrary 返回 0
- javascript - 当页面滚动到达位置时,滚动按钮到位置
- java - scala中的模式匹配。当参数表现出多态性或者是子类时的行为是什么::
- javascript - 从未从 IOT-Core 调用的 Lambda 函数
- php - Symfony - 尝试使用 ControllerResolver 时出现异常
- google-app-engine - Google API 请求停止工作
- python - 在 Keras 中为 fit_generate() 创建自定义 data_generator
- c# - 当前上下文中不存在名称“表”
- iis - 我如何无法通过 ejabberd 配置域,替换 localhost:5280/admin?