我从事件中返回了以下内容,
"epochMilli": 1669288500000,
"timezoneOffsetInSeconds": -18000
我需要使用这个并将其转换为使用JavaScript获取日,月和年的日期。
我无法在JavaScript中找到任何函数来做到这一点。我在Java中也发现了同样的情况:
OffsetDateTime offsetdatetime = Instant.ofEpochSecond(time).atOffset(ZoneOffset.ofTotalSeconds(offset));
LocalDate localdate = offsetDateTime.toLocalDate();
如何在JavaScript中实现相同的功能?
假设您希望年/月/日根据时区与所提供的偏移量,您可以很容易地做到这一点。关键是只使用Date
对象的UTC*
方法,并在调用任何这些方法之前通过偏移量调整毫秒数。这是不清晰的代码…它需要详尽的注释来向读者解释它实际上不是正在读取的UTC值,而是你滥用Date
来假装它是UTC值以便读取日期。
function getDateInOffsetTimeZone(epochMilli, offsetSeconds) {
const adjustedMilli = epochMilli + offsetSeconds * 1000;
const date = new Date(adjustedMilli);
return { year: date.getUTCFullYear(), month: date.getUTCMonth() + 1, day: date.getUTCDate() };
}
getDateInOffsetTimeZone(1669288500000, -18000);
// => { year: 2022, month: 11, day: 24 }
或者你可以用时态来写,这是一种改进的、即将推出的JavaScript日期/时间API,它提供了一种更清晰的方法来获取日期,而无需手动计算偏移量,也不必使用UTC。
import { Temporal } from '@js-temporal/polyfill';
function getDateInOffsetTimeZone(epochMilli, offsetSeconds) {
const instant = Temporal.Instant.fromEpochMilliseconds(epochMilli);
const offsetSign = offsetSeconds < 0 ? '-' : '+';
const offsetAsTime = new Temporal.PlainTime().add({ seconds: Math.abs(offsetSeconds) });
const offsetString = `${offsetSign}${offsetAsTime.toString()}`;
return instant.toZonedDateTimeISO(offsetString).toPlainDate();
}
getDateInOffsetTimeZone(1669288500000, -18000);
// => a Temporal.PlainDate object with { year: 2022, month: 11, day: 24 }
请注意,同样的utc滥用技巧也适用于时态,尽管如上所述,我不建议这样做,因为它可能会让读者感到困惑。
function getDateInOffsetTimeZone(epochMilli, offsetSeconds) {
return Temporal.Instant.fromEpochMilliseconds(epochMilli)
.toZonedDateTimeISO('UTC')
.add({ seconds: offsetSeconds })
.toPlainDate();
}
getDateInOffsetTimeZone(1669288500000, -18000);
// => a Temporal.PlainDate object with { year: 2022, month: 11, day: 24 }
需要注意的一点是:offsetSeconds
符号的含义是模糊的,这取决于生成它的是谁。例如,我住在加利福尼亚,在冬天,我住的地方的偏移量写为-08:00
。但是new Date().getTimezoneOffset()/60
返回8
。两者都不是正式的正确或不正确;两者都表示距离UTC的小时数,但符号是相反的!因此,在使用上述任何代码之前,请确保您知道输入的符号指向哪个方向。
感谢@ptomato(他是我在crime中帮助设计Temporal API的合作伙伴之一)改进了上面的代码示例,并指出了偏移量符号的模糊性。
我建议使用像luxon
这样的库来获取不同时区的时间。
您可以创建一个FixedTimeZone
对象来表示所讨论的区域,传入以分钟为单位的偏移量。
我们现在可以在该区域创建一个DateTime,使用DateTime.fromMillis
,并将该区域对象传递给函数。
年、月、日的值可以从它们各自的属性中检索。
const { DateTime, FixedOffsetZone } = luxon;
const epochMilli = 1669288500000;
const timezoneOffsetInSeconds = -18000;
const zone = new FixedOffsetZone(timezoneOffsetInSeconds / 60)
const dt = DateTime.fromMillis(epochMilli, { zone });
console.log('Year:', dt.year);
console.log('Month:', dt.month);
console.log('Day:', dt.day);
console.log('Date (formatted):', dt.toFormat('yyyy-MM-dd HH:mm:ss'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/luxon/3.0.1/luxon.min.js" integrity="sha512-6ZJuab/UnRq1muTChgrVxJhSgygmL2GMLVmSJN7pcBEqJ1dWPbqN9CiZ6U3HrcApTIJsLnMgXYBYgtVkJ8fWiw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>