Angular:日期时区全局参数设置
Angular: Date Timezone Global parameter setting
我正在寻找方法
将 construction/declaration 的全新日期转换为太平洋标准时间。 (没有团队中的每个开发人员手动设置时区)
此外,在 HTML、console.log
等
中显示的日期应显示为太平洋时区
let test = new Date(2019, 3, 5);
console.log(test);
如何做到这一点? Angular 中是否有一个全局参数来设置它,也许在配置文件中?
*我们代码库中有500行日期代码,需要这个全局转换。有时当人们在不同的时区工作时,应用程序会呈现不同的时区日期。需要更正以前人的代码。
目前无法将这些行转换为 Moment,在当前代码库中使用 Date。
此外,这是一个合适的解决方案吗? tzutil /s "Pacific Standard Time"
,刚刚在 google
中了解到这个
处理日期会让您发疯。使用客户端日期的最大问题是您必须依赖正确设置日期、时间和时区的客户端机器。您始终最好在服务器上创建日期,这样您就可以控制时钟。
拥有一个 api 端点,returns 一个适合你的约会对象是最可靠的选择。往返服务器的开销是非常值得的。
我完全同意@Adrian Brand 的观点。此外,这不是 Angular 问题。这更像是您在申请中处理约会时间的方式。
根据我的经验。使用内置 JavaScript Date.
来做这个日期时间的事情总是很棘手
此外,为了处理太平洋时间,您可能需要处理夏令时。这本身就是另一个问题。
The Pacific Time Zone (PT) is a time zone encompassing parts of western Canada, the western United States, and western Mexico. Places in this zone observe standard time by subtracting eight hours from Coordinated Universal Time (UTC−08:00)
. During daylight saving time, a time offset of UTC−07:00
is used.
我假设您仍将数据作为 ISO
格式发送到服务器。
所以我在新加坡,请参阅以下正常 Date 构造函数的结果。
var date = new Date(2019, 3, 5)
。 //Fri Apr 05 2019 00:00:00 GMT+0800 (Singapore Standard Time)
date.toISOString()
//2019-04-04T16:00:00.000Z
。因为新加坡是 +08:00
,比 UTC 早 8 小时。
因此,如果您希望始终执行新日期以得到 PST 时间,这意味着
var date = new Date(2019, 3, 5)
// Fri Apr 05 2019 00:00:00 GMT-0700 (Pacific Standard Time)
date.toISOString()
//2019-04-05T08:00:00.000Z
。因为太平洋标准时间 -08:00
,比 UTC 晚 8 小时。 -07:00
的夏令时话题,我留给你
您需要
- 重写 Date 构造函数,完全不推荐这样做。
- 在日期构造中添加一个新方法来显示或给你一个正确的 ISO 格式,但要考虑 PST 时区。这涉及一些字符串替换和一些用于偏移计算的数学运算。
添加在 PST 中显示字符串的方法
如果您使用 var date = new Date(2019, 3, 5)
的确切日期执行构造函数。您只需添加一个新方法调用 toPSTString()
并使用正则表达式将 ()
中的文本替换为 Pacific Standard Time
并将 GMT+xxx
中的文本替换为 GMT-08:00
因为值日期是绝对的。
Date.prototype.toPSTString = function () {
let date = this.toString();
//date.replace.... easy part, you could use Regex to do it
return date;
};
但是如果您在构造函数中传递了 ISO String 格式的日期或毫秒数。处理起来会非常棘手。例如,如果你做 new Date("2019-04-05T07:00:00.000Z")
,你想看到什么?
见下文,了解我如何根据偏移量差异输出 ISO 字符串。它可能会给你一些想法/
添加一种方法来获取考虑 PST -08:00 时区的 ISO 格式的字符串
new Date
将始终在您的本地计算机时区工作。所以如果我在新加坡,我做 new Date(2019, 3, 5).toISOString()
,它总是给我 2019-04-04T16:00:00.000Z
,而不是你期望的 2019-04-05T08:00:00.000Z
。
您也可以覆盖 JS 函数以输出 UTC 日期,但要考虑 PST 时间。
Date.prototype.toPSTString = function () {
function convertMinuteToMillisecond(mins) {
return mins * 60 * 1000;
}
let localDateOffsetToUtc = this.getTimezoneOffset(); //the offset between the user local timezone with UTC. In my use case of Singapore, it give me -480.
const offSetBetweenPSTAndUTC = 480;
let offsetBetweenPSTAndLocal = offSetBetweenPSTAndUTC - localDateOffsetToUtc;
let newDate = new Date(
this.getTime() + convertMinuteToMillisecond(offsetBetweenPSTAndLocal)
);
return newDate.toISOString();
};
var date = new Date(2019, 3, 5);
date.toISOString(); //"2019-04-04T16:00:00.000Z" Singapore
date.toPSTString(); //"2019-04-05T08:00:00.000Z" PST
输出看起来是正确的。我还没有真正测试过,但希望你能明白。
但通常情况下,如果您在新加坡,您希望看到新加坡时区的日期。没有人关心 PST 时区。如果您在伦敦,也一样,您不想看到新加坡或 PST 时区的时间。我想你可能想考虑一下。因为如果您的应用程序正在成长,修复此类问题会变得越来越困难。
我写了我如何 handle the timezone and locale in my blog。在我的用例中,我使用 moment.js
而且,服务器端需要在这方面支持我。如果你想有更多的想法,你也可以看看
这应该可以做到。
传入 null
以获取太平洋日期 now
,或传入任何日期以将其转换为太平洋日期:
pacificTimeOfDate(d:Date=null) {
if (!d)
d = new Date();
var year = d.getUTCFullYear();
var month = d.getUTCMonth();
var day = d.getUTCDate();
var hours = d.getUTCHours();
var minutes = d.getUTCMinutes();
var seconds = d.getUTCSeconds();
var utcDate = new Date(year, month, day, hours, minutes, seconds);
utcDate.setMinutes(utcDate.getMinutes() - 420);
return utcDate
}
最好使用ISO 8601格式的日期时间。请查看使用 ISO-8601 日期格式的原因和好处。 https://www.iso.org/iso-8601-date-and-time-format.html
完整的 post 在这里 Implementing ISO 8601 date time format in Angular
ISO 8601 can be used by anyone who wants to use a standardized way of
presenting:
Date,
Time of day,
Coordinated Universal Time (UTC),
Date and time,
Time intervals,
Recurring time intervals
您可以使用此代码以您想要的方式使用格式。希望对您有所帮助。
export interface HashTable<T> {
[key: string]: T;
}
import { Injectable } from '@angular/core';
import { HashTable } from './hash-table';
type FormatFunc = (date: Date) => string;
@Injectable({
providedIn: 'root'
})
export class DateFormat {
formattingTokenFunc: HashTable<FormatFunc> = {};
private formattingTokens = /(HH?|HH?|hh?|mm?|ss?|MM?|dd?|yy?y?y?|.)/g;
constructor() {
// add years function
const getYearFunc = (date: Date) => date.getFullYear().toString();
// Year, no leading zero (e.g. 2015 would be 15)
this.addFormatToken('y', 0, (date: Date) =>
(date.getFullYear() % 100).toString()
);
this.addFormatToken('yyy', 0, getYearFunc);
this.addFormatToken('yyyy', 0, getYearFunc);
// Year, leading zero (e.g. 2015 would be 015)
this.addFormatToken('yy', 3, (date: Date) =>
(date.getFullYear() % 100).toString()
);
// add months function
const getMonthFunc = (date: Date) => (date.getMonth() + 1).toString();
this.addFormatToken('M', 0, getMonthFunc);
this.addFormatToken('MM', 2, getMonthFunc);
// add day function
const getDayFunc = (date: Date) => date.getDate().toString();
this.addFormatToken('d', 0, getDayFunc);
this.addFormatToken('dd', 2, getDayFunc);
// add hours function
const get12HrFunc = (date: Date) => (date.getHours() % 12).toString();
// 12-hour clock, with a leading 0 eg (e.g. 06)
this.addFormatToken('hh', 2, get12HrFunc);
// 12-hour clock hour
this.addFormatToken('h', 0, get12HrFunc);
const get24HrFunc = (date: Date) => date.getHours().toString();
this.addFormatToken('HH', 2, get24HrFunc);
this.addFormatToken('H', 0, get24HrFunc);
// add minute function
const getMinFunc = (date: Date) => date.getMinutes().toString();
this.addFormatToken('m', 0, getMinFunc);
// Minutes with a leading zero
this.addFormatToken('mm', 2, getMinFunc);
// add seconds function
const getSecFunc = (date: Date) => date.getSeconds().toString();
this.addFormatToken('s', 0, getSecFunc);
this.addFormatToken('ss', 2, getSecFunc);
}
formatToISO8601Date(date: Date | string): string {
return this.format(date, 'yyyy-MM-dd');
}
format(date: Date | string, format: string): string {
const finalDate = date instanceof Date ? date : new Date(date);
const matches = format.match(this.formattingTokens);
let result = '';
matches.forEach(match => {
// const hasFunc = this.formattingTokenFunc.hasOwnProperty('match');
const formatFunc = this.formattingTokenFunc[match];
result += formatFunc ? formatFunc(finalDate) : match;
});
return result;
}
prefixZero(length: number, input: string): string {
return `${Math.pow(10, length)}${input}`.slice(-1 * length);
}
prefixZeroFunc(length: number, formatFunc: FormatFunc): FormatFunc {
return (c: Date) => this.prefixZero(length, formatFunc(c));
}
private addFormatToken(
token: string,
addZeroesLength: number,
// formatFunc: ((date: Date) => string)
formatFunc: FormatFunc
): void {
this.formattingTokenFunc[token] =
addZeroesLength > 0
? this.prefixZeroFunc(addZeroesLength, formatFunc)
: formatFunc;
}
}
我正在寻找方法
将 construction/declaration 的全新日期转换为太平洋标准时间。 (没有团队中的每个开发人员手动设置时区)
此外,在 HTML、
中显示的日期应显示为太平洋时区console.log
等let test = new Date(2019, 3, 5); console.log(test);
如何做到这一点? Angular 中是否有一个全局参数来设置它,也许在配置文件中?
*我们代码库中有500行日期代码,需要这个全局转换。有时当人们在不同的时区工作时,应用程序会呈现不同的时区日期。需要更正以前人的代码。
目前无法将这些行转换为 Moment,在当前代码库中使用 Date。
此外,这是一个合适的解决方案吗? tzutil /s "Pacific Standard Time"
,刚刚在 google
处理日期会让您发疯。使用客户端日期的最大问题是您必须依赖正确设置日期、时间和时区的客户端机器。您始终最好在服务器上创建日期,这样您就可以控制时钟。
拥有一个 api 端点,returns 一个适合你的约会对象是最可靠的选择。往返服务器的开销是非常值得的。
我完全同意@Adrian Brand 的观点。此外,这不是 Angular 问题。这更像是您在申请中处理约会时间的方式。
根据我的经验。使用内置 JavaScript Date.
来做这个日期时间的事情总是很棘手此外,为了处理太平洋时间,您可能需要处理夏令时。这本身就是另一个问题。
The Pacific Time Zone (PT) is a time zone encompassing parts of western Canada, the western United States, and western Mexico. Places in this zone observe standard time by subtracting eight hours from Coordinated Universal Time
(UTC−08:00)
. During daylight saving time, a time offset ofUTC−07:00
is used.
我假设您仍将数据作为 ISO
格式发送到服务器。
所以我在新加坡,请参阅以下正常 Date 构造函数的结果。
var date = new Date(2019, 3, 5)
。 //Fri Apr 05 2019 00:00:00 GMT+0800 (Singapore Standard Time)
date.toISOString()
//2019-04-04T16:00:00.000Z
。因为新加坡是+08:00
,比 UTC 早 8 小时。
因此,如果您希望始终执行新日期以得到 PST 时间,这意味着
var date = new Date(2019, 3, 5)
//Fri Apr 05 2019 00:00:00 GMT-0700 (Pacific Standard Time)
date.toISOString()
//2019-04-05T08:00:00.000Z
。因为太平洋标准时间-08:00
,比 UTC 晚 8 小时。-07:00
的夏令时话题,我留给你
您需要
- 重写 Date 构造函数,完全不推荐这样做。
- 在日期构造中添加一个新方法来显示或给你一个正确的 ISO 格式,但要考虑 PST 时区。这涉及一些字符串替换和一些用于偏移计算的数学运算。
添加在 PST 中显示字符串的方法
如果您使用 var date = new Date(2019, 3, 5)
的确切日期执行构造函数。您只需添加一个新方法调用 toPSTString()
并使用正则表达式将 ()
中的文本替换为 Pacific Standard Time
并将 GMT+xxx
中的文本替换为 GMT-08:00
因为值日期是绝对的。
Date.prototype.toPSTString = function () {
let date = this.toString();
//date.replace.... easy part, you could use Regex to do it
return date;
};
但是如果您在构造函数中传递了 ISO String 格式的日期或毫秒数。处理起来会非常棘手。例如,如果你做 new Date("2019-04-05T07:00:00.000Z")
,你想看到什么?
见下文,了解我如何根据偏移量差异输出 ISO 字符串。它可能会给你一些想法/
添加一种方法来获取考虑 PST -08:00 时区的 ISO 格式的字符串
new Date
将始终在您的本地计算机时区工作。所以如果我在新加坡,我做 new Date(2019, 3, 5).toISOString()
,它总是给我 2019-04-04T16:00:00.000Z
,而不是你期望的 2019-04-05T08:00:00.000Z
。
您也可以覆盖 JS 函数以输出 UTC 日期,但要考虑 PST 时间。
Date.prototype.toPSTString = function () {
function convertMinuteToMillisecond(mins) {
return mins * 60 * 1000;
}
let localDateOffsetToUtc = this.getTimezoneOffset(); //the offset between the user local timezone with UTC. In my use case of Singapore, it give me -480.
const offSetBetweenPSTAndUTC = 480;
let offsetBetweenPSTAndLocal = offSetBetweenPSTAndUTC - localDateOffsetToUtc;
let newDate = new Date(
this.getTime() + convertMinuteToMillisecond(offsetBetweenPSTAndLocal)
);
return newDate.toISOString();
};
var date = new Date(2019, 3, 5);
date.toISOString(); //"2019-04-04T16:00:00.000Z" Singapore
date.toPSTString(); //"2019-04-05T08:00:00.000Z" PST
输出看起来是正确的。我还没有真正测试过,但希望你能明白。
但通常情况下,如果您在新加坡,您希望看到新加坡时区的日期。没有人关心 PST 时区。如果您在伦敦,也一样,您不想看到新加坡或 PST 时区的时间。我想你可能想考虑一下。因为如果您的应用程序正在成长,修复此类问题会变得越来越困难。
我写了我如何 handle the timezone and locale in my blog。在我的用例中,我使用 moment.js
而且,服务器端需要在这方面支持我。如果你想有更多的想法,你也可以看看
这应该可以做到。
传入 null
以获取太平洋日期 now
,或传入任何日期以将其转换为太平洋日期:
pacificTimeOfDate(d:Date=null) {
if (!d)
d = new Date();
var year = d.getUTCFullYear();
var month = d.getUTCMonth();
var day = d.getUTCDate();
var hours = d.getUTCHours();
var minutes = d.getUTCMinutes();
var seconds = d.getUTCSeconds();
var utcDate = new Date(year, month, day, hours, minutes, seconds);
utcDate.setMinutes(utcDate.getMinutes() - 420);
return utcDate
}
最好使用ISO 8601格式的日期时间。请查看使用 ISO-8601 日期格式的原因和好处。 https://www.iso.org/iso-8601-date-and-time-format.html
完整的 post 在这里 Implementing ISO 8601 date time format in Angular
ISO 8601 can be used by anyone who wants to use a standardized way of presenting:
Date,
Time of day,
Coordinated Universal Time (UTC),
Date and time,
Time intervals,
Recurring time intervals
您可以使用此代码以您想要的方式使用格式。希望对您有所帮助。
export interface HashTable<T> {
[key: string]: T;
}
import { Injectable } from '@angular/core';
import { HashTable } from './hash-table';
type FormatFunc = (date: Date) => string;
@Injectable({
providedIn: 'root'
})
export class DateFormat {
formattingTokenFunc: HashTable<FormatFunc> = {};
private formattingTokens = /(HH?|HH?|hh?|mm?|ss?|MM?|dd?|yy?y?y?|.)/g;
constructor() {
// add years function
const getYearFunc = (date: Date) => date.getFullYear().toString();
// Year, no leading zero (e.g. 2015 would be 15)
this.addFormatToken('y', 0, (date: Date) =>
(date.getFullYear() % 100).toString()
);
this.addFormatToken('yyy', 0, getYearFunc);
this.addFormatToken('yyyy', 0, getYearFunc);
// Year, leading zero (e.g. 2015 would be 015)
this.addFormatToken('yy', 3, (date: Date) =>
(date.getFullYear() % 100).toString()
);
// add months function
const getMonthFunc = (date: Date) => (date.getMonth() + 1).toString();
this.addFormatToken('M', 0, getMonthFunc);
this.addFormatToken('MM', 2, getMonthFunc);
// add day function
const getDayFunc = (date: Date) => date.getDate().toString();
this.addFormatToken('d', 0, getDayFunc);
this.addFormatToken('dd', 2, getDayFunc);
// add hours function
const get12HrFunc = (date: Date) => (date.getHours() % 12).toString();
// 12-hour clock, with a leading 0 eg (e.g. 06)
this.addFormatToken('hh', 2, get12HrFunc);
// 12-hour clock hour
this.addFormatToken('h', 0, get12HrFunc);
const get24HrFunc = (date: Date) => date.getHours().toString();
this.addFormatToken('HH', 2, get24HrFunc);
this.addFormatToken('H', 0, get24HrFunc);
// add minute function
const getMinFunc = (date: Date) => date.getMinutes().toString();
this.addFormatToken('m', 0, getMinFunc);
// Minutes with a leading zero
this.addFormatToken('mm', 2, getMinFunc);
// add seconds function
const getSecFunc = (date: Date) => date.getSeconds().toString();
this.addFormatToken('s', 0, getSecFunc);
this.addFormatToken('ss', 2, getSecFunc);
}
formatToISO8601Date(date: Date | string): string {
return this.format(date, 'yyyy-MM-dd');
}
format(date: Date | string, format: string): string {
const finalDate = date instanceof Date ? date : new Date(date);
const matches = format.match(this.formattingTokens);
let result = '';
matches.forEach(match => {
// const hasFunc = this.formattingTokenFunc.hasOwnProperty('match');
const formatFunc = this.formattingTokenFunc[match];
result += formatFunc ? formatFunc(finalDate) : match;
});
return result;
}
prefixZero(length: number, input: string): string {
return `${Math.pow(10, length)}${input}`.slice(-1 * length);
}
prefixZeroFunc(length: number, formatFunc: FormatFunc): FormatFunc {
return (c: Date) => this.prefixZero(length, formatFunc(c));
}
private addFormatToken(
token: string,
addZeroesLength: number,
// formatFunc: ((date: Date) => string)
formatFunc: FormatFunc
): void {
this.formattingTokenFunc[token] =
addZeroesLength > 0
? this.prefixZeroFunc(addZeroesLength, formatFunc)
: formatFunc;
}
}