设置全局 Moment 区域设置后,Moment-Timezone 使用默认区域设置

Moment-Timezone is using default locale after global Moment locale is set

提问人:Stavros_S 提问时间:5/31/2017 最后编辑:Stavros_S 更新时间:11/19/2023 访问量:10797

问:

我正在构建一个用 Typescript 编写的应用程序,它使用 Moment.js 和 moment-timezone 的功能。我需要本地化应用程序中的日期和时间戳,因此在主文件中,我使用设备的语言设置了时刻的区域设置。app.ts

更新:这是示例文件的要点,其中包含其他注释 https://gist.github.com/spstratis/fa853f9750a095d4acd0d1196a285be9

app.ts

import * as moment from 'moment/min/moment-with-locales';

let language = appUtil.getPhoneLanguage();

moment.locale(language);

// the expected locale is printed
console.log("Moment Locale = " + moment.locale());

问题是,在这个实用程序模块中,当我导入 moment-timezone 时,即使我在主文件中全局设置了 moment's locale,它也默认为'en'locale。app.ts

以下是我的两个实用方法,如果 moment-timezone 默认为“en”,我该如何本地化相对日期字符串和月份?

我尝试将 .locale(locale) 添加到 moment 方法中,但这并没有改变任何东西。如果我导入了 moment 而不是 moment-timezone,它适用于某些方法,但在需要使用时区实用程序的任何方法上都失败了。

date-util.ts

import * as moment from 'moment-timezone';

export function dateRelativeTime(value): string {
  let timezoneId = appCache.getTimezoneId();
  let localTime = _getLocalUtcDateString(value, timezoneId);
  let dateMoment = moment(localTime, "MM/DD/YYYY hh:mm:ss A");
  let formatedDate = dateMoment.tz(timezoneId).fromNow();

  return formatedDate;
};

export function localizedMonths(): ValueList {
  let m = moment("2016");
  let months = new ValueList([]);
  for (var i = 0; i < 12; i++) {
    months.push({ ValueMember: [i + 1], DisplayMember: m.month(i).format('MMMM') });
  }

  return months;
};
JavaScript 日期 时间 打字稿 momentjs

评论

0赞 BogdanBiv 5/31/2017
你能用 TS 和两个时刻库设置一个要点吗?
0赞 Stavros_S 5/31/2017
@BogdanBiv使用我的所有代码?
3赞 VincenzoC 5/31/2017
作为旁注:您可以使用来获取月份名称的本地化数组,请参阅文档中的访问特定于区域设置的功能localeData = moment.localeData(); localeData.months();
0赞 BogdanBiv 5/31/2017
@Stavros_S:这正是重点:将你的问题隔离在可以共享的较小项目中。
1赞 Matt Johnson-Pint 6/1/2017
@VincenzoC - 或者只是moment.months()

答:

0赞 BogdanBiv 5/31/2017 #1

你试过吗?.format('')

moment.locale();         // en
moment().format('LT');   // 6:27 PM
moment().format('LTS');  // 6:27:51 PM
moment().format('L');    // 05/31/2017
moment().format('l');    // 5/31/2017
moment().format('LL');   // May 31, 2017
moment().format('ll');   // May 31, 2017
moment().format('LLL');  // May 31, 2017 6:27 PM
moment().format('lll');  // May 31, 2017 6:27 PM
moment().format('LLLL'); // Wednesday, May 31, 2017 6:27 PM
moment().format('llll'); // Wed, May 31, 2017 6:27 PM

更新:还要确保你的时刻库是其中有语言环境的库:https://momentjs.com/ 指定有两个时刻库,有 ( moment-with-locales.js ) 和没有语言环境 ( moment.js )。

评论

0赞 Stavros_S 5/31/2017
是的 - 但它仍然以英语返回值。即使我设置了 moment.locale(“es”)。在我看来,moment-timezone 不尊重另一个文件中 moment 设置的区域设置......我正在创建一个要点来帮助更好地解释事情。
0赞 Stavros_S 5/31/2017
我在这个问题上添加了一个要点。您会注意到我已经在导入中使用了 moment-with-locales。
0赞 Matt Johnson-Pint 6/1/2017 #2

你导入的时刻错了。别这样:

import * as moment from 'moment/min/moment-with-locales';

只需这样做:

import * as moment from 'moment';

它将在您使用各个区域设置时加载它们(在 Node.js 上),然后您将共享时刻时区使用的相同时刻依赖项,因此您的全局区域设置将贯彻执行。

评论

0赞 Stavros_S 6/1/2017
这实际上是我最初导入它的方式。不过它没有用。仅导入时,即使在设置了区域设置后也是如此。如果我之后立即注销全局区域设置,即使尝试将其设置为“es”,它也会打印出“en”
0赞 Matt Johnson-Pint 6/1/2017
您还需要导入所需的每个本地,如文档中所示。除非您在 Node.js 上运行它,在这种情况下,它将在您调用它们时异步加载它们。
0赞 Stavros_S 6/1/2017
我仍然没有任何运气,即使在复制了文档显示的内容之后。
0赞 Matt Johnson-Pint 6/1/2017
这里的这些对你不起作用?
0赞 Stavros_S 6/4/2017
他们不是,我已经更新了我的要点以显示我如何加载它的示例。gist.github.com/spstratis/fa853f9750a095d4acd0d1196a285be9
4赞 Jorgé Reyniers 4/10/2019 #3

我在 Typescript 中遇到了同样的问题。我想使用 moment-timezone 将时区设置为欧洲/布鲁塞尔并将 locale 设置为比利时荷兰语,我是这样解决的:

import 'moment/locale/nl-be';
import * as momentTZ from 'moment-timezone';
momentTZ.locale("nl-be");
momentTZ.tz.setDefault("Europe/Brussels");

如果你想在项目中使用moment,现在使用momentTZ,就像这个f.e.

const exampleDate = momentTZ().format('dddd D MMMM');
-1赞 foloinfo 12/9/2021 #4

我不知道为什么,但我突然遇到了同样的问题。
在使用带有区域设置的 moment 和 moment-timezone 时,您似乎需要一些额外的配置。

以下是仅使用一种区域设置时的最低设置。

import 'moment/locale/ja' // or whatever locale you want
import moment from 'moment'
import memontTZ from 'moment-timezone'
mementTZ.defineLocale('ja', moment.localData()._config)

我相信您可以按照以下示例配置多个区域设置。
编号: https://github.com/moment/moment-timezone/issues/647#issuecomment-439600573

1赞 CodingEra 7/20/2023 #5

我们也有这个问题。这是一个非常丑陋的解决方法,因为两者都将在项目中,但包取决于包,所以我想它们都会存在。momentmoment-timezonemoment-timezonemoment

这个想法是将本地化应用于时刻,然后将其用于moment-timezone

import moment from 'moment-timezone';
import momentLocale from 'moment';

const localeLang = ‘pt’;
moment.tz.setDefault('America/Sao_Paulo');
momentLocale.locale(localeLang);
moment.localeData(localeLang);
moment.defineLocale(localeLang, momentLocale.localeData()._config);
0赞 zyc 11/7/2023 #6

对于多语言环境,请使用 Moment.js 自定义

import moment from 'moment-timezone';
import momentLocale from 'moment';
import 'moment/locale/en-gb';
import 'moment/locale/es';
import 'moment/locale/fr';
import 'moment/locale/pt';
import 'moment/locale/pt-br';
const localeLang = 'pt-br';
momentLocale.locale(localeLang);

const tz = 'America/Bahia';
moment.tz.setDefault(tz);
moment.updateLocale(localeLang, momentLocale.localeData()._config);

在此之后,您应该始终导入,一切都会好起来的:moment-timezone

import moment from 'moment-timezone';