From de98989a81fb1028d9eace9f2d07690d14c73aca Mon Sep 17 00:00:00 2001 From: Vlad Georgescu Date: Mon, 28 Oct 2024 16:02:35 +0000 Subject: [PATCH 01/11] Update Chinese trad timestamp object --- .../timeFormatTests/expectedFormats.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/app/legacy/containers/ArticleTimestamp/timeFormatTests/expectedFormats.json b/src/app/legacy/containers/ArticleTimestamp/timeFormatTests/expectedFormats.json index 4e9a88dcc94..77f50ac0e3a 100644 --- a/src/app/legacy/containers/ArticleTimestamp/timeFormatTests/expectedFormats.json +++ b/src/app/legacy/containers/ArticleTimestamp/timeFormatTests/expectedFormats.json @@ -509,12 +509,12 @@ "exact date and time with timezone": "2019年7月12日下午12点55分" }, "trad": { - "one minute ago": "1 分钟前", - "five minutes ago": "5 分钟前", - "one hour ago": "1 小时前", - "five hours ago": "5 小时前", + "one minute ago": "1 分鐘前", + "five minutes ago": "5 分鐘前", + "one hour ago": "1 小時前", + "five hours ago": "5 小時前", "exact date": "2018年10月10日", - "exact date and time with timezone": "2019年7月12日下午12点55分" + "exact date and time with timezone": "2019年7月12日下午12時55分" } } } From 16bc626d93418e682855a1b098086a9eed009cb2 Mon Sep 17 00:00:00 2001 From: Karina Thomas Date: Mon, 28 Oct 2024 17:48:11 +0000 Subject: [PATCH 02/11] Adding override translations for minutes/hours for zh-ch --- .../psammead/psammead-locales/moment/zh-cn.js | 14 + .../psammead-locales/moment/zh-cn.test.js | 479 ++++++++++++++++++ 2 files changed, 493 insertions(+) create mode 100644 src/app/legacy/psammead/psammead-locales/moment/zh-cn.js create mode 100644 src/app/legacy/psammead/psammead-locales/moment/zh-cn.test.js diff --git a/src/app/legacy/psammead/psammead-locales/moment/zh-cn.js b/src/app/legacy/psammead/psammead-locales/moment/zh-cn.js new file mode 100644 index 00000000000..c02e6d5b1b8 --- /dev/null +++ b/src/app/legacy/psammead/psammead-locales/moment/zh-cn.js @@ -0,0 +1,14 @@ +const moment = require('moment'); +require('moment/locale/zh-cn'); + +moment.updateLocale('zh-cn', { + relativeTime: { + // these keys have been overridden with our translations + // some other keys have been left as set upstream + // see https://github.com/moment/moment/blob/develop/src/locale/zh-cn.js + m: '1 分鐘', + mm: '%d 分鐘', + h: '1 小時', + hh: '%d 小時', + }, +}); diff --git a/src/app/legacy/psammead/psammead-locales/moment/zh-cn.test.js b/src/app/legacy/psammead/psammead-locales/moment/zh-cn.test.js new file mode 100644 index 00000000000..3e9eb468252 --- /dev/null +++ b/src/app/legacy/psammead/psammead-locales/moment/zh-cn.test.js @@ -0,0 +1,479 @@ +import moment from 'moment'; +import './zh-cn'; + +moment.locale('zh-cn'); + +// This asset overrides the gunit assertion done in the moment codebase. +// Format and styling of this file has been keep consistent with the official moment tests. +// An example of these tests can be seen at https://github.com/moment/moment/blob/develop/src/test/locale/en-gb.js +const assert = { + equal: (val1, val2, scenario) => + it(scenario, () => expect(val1).toEqual(val2)), +}; + +describe('zh-cn', () => { + describe('parse', () => { + const tests = + '一月 1月_二月 2月_三月 3月_四月 4月_五月 5月_六月 6月_七月 7月_八月 8月_九月 9月_十月 10月_十一月 11月_十二月 12月'.split( + '_' + ); + + function equalTest(input, mmm, i) { + assert.equal( + moment(input, mmm).month(), + i, + `${input} should be month ${i + 1}` + ); + } + + let i; + for (i = 0; i < 12; i += 1) { + tests[i] = tests[i].split(' '); + equalTest(tests[i][0], 'MMM', i); + equalTest(tests[i][1], 'MMM', i); + equalTest(tests[i][0], 'MMMM', i); + equalTest(tests[i][1], 'MMMM', i); + equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i); + equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i); + equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i); + equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i); + } + }); + + const a = [ + ['dddd, MMMM Do YYYY, a h:mm:ss', '星期日, 二月 14日 2010, 下午 3:25:50'], + ['ddd, Ah', '周日, 下午3'], + ['M Mo MM MMMM MMM', '2 2月 02 二月 2月'], + ['YYYY YY', '2010 10'], + ['D Do DD', '14 14日 14'], + ['d do dddd ddd dd', '0 0日 星期日 周日 日'], + ['DDD DDDo DDDD', '45 45日 045'], + ['w wo ww', '6 6周 06'], + ['h hh', '3 03'], + ['H HH', '15 15'], + ['m mm', '25 25'], + ['s ss', '50 50'], + ['a A', '下午 下午'], + ['[这年的第] DDDo', '这年的第 45日'], + ['LTS', '15:25:50'], + ['L', '2010/02/14'], + ['LL', '2010年2月14日'], + ['LLL', '2010年2月14日下午3点25分'], + ['LLLL', '2010年2月14日星期日下午3点25分'], + ['l', '2010/2/14'], + ['ll', '2010年2月14日'], + ['lll', '2010年2月14日 15:25'], + ['llll', '2010年2月14日星期日 15:25'], + ]; + + describe.each(a)('format %s', (formatString, expectedDate) => { + const b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)); + assert.equal( + b.format(formatString), + expectedDate, + `${formatString} ---> ${expectedDate}` + ); + }); + + describe('format ordinal', () => { + assert.equal(moment([2011, 0, 1]).format('DDDo'), '1日', '1日'); + assert.equal(moment([2011, 0, 2]).format('DDDo'), '2日', '2日'); + assert.equal(moment([2011, 0, 3]).format('DDDo'), '3日', '3日'); + assert.equal(moment([2011, 0, 4]).format('DDDo'), '4日', '4日'); + assert.equal(moment([2011, 0, 5]).format('DDDo'), '5日', '5日'); + assert.equal(moment([2011, 0, 6]).format('DDDo'), '6日', '6日'); + assert.equal(moment([2011, 0, 7]).format('DDDo'), '7日', '7日'); + assert.equal(moment([2011, 0, 8]).format('DDDo'), '8日', '8日'); + assert.equal(moment([2011, 0, 9]).format('DDDo'), '9日', '9日'); + assert.equal(moment([2011, 0, 10]).format('DDDo'), '10日', '10日'); + + assert.equal(moment([2011, 0, 11]).format('DDDo'), '11日', '11日'); + assert.equal(moment([2011, 0, 12]).format('DDDo'), '12日', '12日'); + assert.equal(moment([2011, 0, 13]).format('DDDo'), '13日', '13日'); + assert.equal(moment([2011, 0, 14]).format('DDDo'), '14日', '14日'); + assert.equal(moment([2011, 0, 15]).format('DDDo'), '15日', '15日'); + assert.equal(moment([2011, 0, 16]).format('DDDo'), '16日', '16日'); + assert.equal(moment([2011, 0, 17]).format('DDDo'), '17日', '17日'); + assert.equal(moment([2011, 0, 18]).format('DDDo'), '18日', '18日'); + assert.equal(moment([2011, 0, 19]).format('DDDo'), '19日', '19日'); + assert.equal(moment([2011, 0, 20]).format('DDDo'), '20日', '20日'); + + assert.equal(moment([2011, 0, 21]).format('DDDo'), '21日', '21日'); + assert.equal(moment([2011, 0, 22]).format('DDDo'), '22日', '22日'); + assert.equal(moment([2011, 0, 23]).format('DDDo'), '23日', '23日'); + assert.equal(moment([2011, 0, 24]).format('DDDo'), '24日', '24日'); + assert.equal(moment([2011, 0, 25]).format('DDDo'), '25日', '25日'); + assert.equal(moment([2011, 0, 26]).format('DDDo'), '26日', '26日'); + assert.equal(moment([2011, 0, 27]).format('DDDo'), '27日', '27日'); + assert.equal(moment([2011, 0, 28]).format('DDDo'), '28日', '28日'); + assert.equal(moment([2011, 0, 29]).format('DDDo'), '29日', '29日'); + assert.equal(moment([2011, 0, 30]).format('DDDo'), '30日', '30日'); + + assert.equal(moment([2011, 0, 31]).format('DDDo'), '31日', '31日'); + }); + + describe('format month', () => { + const expected = + '一月 1月_二月 2月_三月 3月_四月 4月_五月 5月_六月 6月_七月 7月_八月 8月_九月 9月_十月 10月_十一月 11月_十二月 12月'.split( + '_' + ); + let i; + for (i = 0; i < expected.length; i += 1) { + assert.equal( + moment([2011, i, 1]).format('MMMM MMM'), + expected[i], + expected[i] + ); + } + }); + + describe('format week', () => { + const expected = + '星期日 周日 日_星期一 周一 一_星期二 周二 二_星期三 周三 三_星期四 周四 四_星期五 周五 五_星期六 周六 六'.split( + '_' + ); + let i; + for (i = 0; i < expected.length; i += 1) { + assert.equal( + moment([2011, 0, 2 + i]).format('dddd ddd dd'), + expected[i], + expected[i] + ); + } + }); + + describe('from', () => { + const start = moment([2007, 1, 28]); + assert.equal( + start.from(moment([2007, 1, 28]).add({ s: 44 }), true), + '几秒', + '44 seconds = a few seconds' + ); + assert.equal( + start.from(moment([2007, 1, 28]).add({ s: 45 }), true), + '1 分鐘', + '45 seconds = a minute' + ); + assert.equal( + start.from(moment([2007, 1, 28]).add({ s: 89 }), true), + '1 分鐘', + '89 seconds = a minute' + ); + assert.equal( + start.from(moment([2007, 1, 28]).add({ s: 90 }), true), + '2 分鐘', + '90 seconds = 2 minutes' + ); + assert.equal( + start.from(moment([2007, 1, 28]).add({ m: 44 }), true), + '44 分鐘', + '44 minutes = 44 minutes' + ); + assert.equal( + start.from(moment([2007, 1, 28]).add({ m: 45 }), true), + '1 小時', + '45 minutes = an hour' + ); + assert.equal( + start.from(moment([2007, 1, 28]).add({ m: 89 }), true), + '1 小時', + '89 minutes = an hour' + ); + assert.equal( + start.from(moment([2007, 1, 28]).add({ m: 90 }), true), + '2 小時', + '90 minutes = 2 hours' + ); + assert.equal( + start.from(moment([2007, 1, 28]).add({ h: 5 }), true), + '5 小時', + '5 hours = 5 hours' + ); + assert.equal( + start.from(moment([2007, 1, 28]).add({ h: 21 }), true), + '21 小時', + '21 hours = 21 hours' + ); + assert.equal( + start.from(moment([2007, 1, 28]).add({ h: 22 }), true), + '1 天', + '22 hours = a day' + ); + assert.equal( + start.from(moment([2007, 1, 28]).add({ h: 35 }), true), + '1 天', + '35 hours = a day' + ); + assert.equal( + start.from(moment([2007, 1, 28]).add({ h: 36 }), true), + '2 天', + '36 hours = 2 days' + ); + assert.equal( + start.from(moment([2007, 1, 28]).add({ d: 1 }), true), + '1 天', + '1 day = a day' + ); + assert.equal( + start.from(moment([2007, 1, 28]).add({ d: 5 }), true), + '5 天', + '5 days = 5 days' + ); + assert.equal( + start.from(moment([2007, 1, 28]).add({ d: 25 }), true), + '25 天', + '25 days = 25 days' + ); + assert.equal( + start.from(moment([2007, 1, 28]).add({ d: 26 }), true), + '1 个月', + '26 days = a month' + ); + assert.equal( + start.from(moment([2007, 1, 28]).add({ d: 30 }), true), + '1 个月', + '30 days = a month' + ); + assert.equal( + start.from(moment([2007, 1, 28]).add({ d: 43 }), true), + '1 个月', + '43 days = a month' + ); + assert.equal( + start.from(moment([2007, 1, 28]).add({ d: 46 }), true), + '2 个月', + '46 days = 2 months' + ); + assert.equal( + start.from(moment([2007, 1, 28]).add({ d: 74 }), true), + '2 个月', + '75 days = 2 months' + ); + assert.equal( + start.from(moment([2007, 1, 28]).add({ d: 76 }), true), + '3 个月', + '76 days = 3 months' + ); + assert.equal( + start.from(moment([2007, 1, 28]).add({ M: 1 }), true), + '1 个月', + '1 month = a month' + ); + assert.equal( + start.from(moment([2007, 1, 28]).add({ M: 5 }), true), + '5 个月', + '5 months = 5 months' + ); + assert.equal( + start.from(moment([2007, 1, 28]).add({ d: 345 }), true), + '1 年', + '345 days = a year' + ); + assert.equal( + start.from(moment([2007, 1, 28]).add({ d: 548 }), true), + '2 年', + '548 days = 2 years' + ); + assert.equal( + start.from(moment([2007, 1, 28]).add({ y: 1 }), true), + '1 年', + '1 year = a year' + ); + assert.equal( + start.from(moment([2007, 1, 28]).add({ y: 5 }), true), + '5 年', + '5 years = 5 years' + ); + }); + + describe('suffix', () => { + assert.equal(moment(30000).from(0), '几秒后', 'prefix'); + assert.equal(moment(0).from(30000), '几秒前', 'prefix'); + }); + + describe('now from now', () => { + assert.equal( + moment().fromNow(), + '几秒前', + 'now from now should display as in the past' + ); + }); + + describe('fromNow', () => { + assert.equal( + moment().add({ s: 30 }).fromNow(), + '几秒后', + 'in a few seconds' + ); + assert.equal(moment().add({ d: 5 }).fromNow(), '5 天后', 'in 5 days'); + }); + + describe('calendar day', () => { + const calendarTime = moment().hours(12).minutes(0).seconds(0); + + assert.equal( + moment(calendarTime).calendar(), + '今天12:00', + 'today at the same time' + ); + assert.equal( + moment(calendarTime).add({ m: 25 }).calendar(), + '今天12:25', + 'Now plus 25 min' + ); + assert.equal( + moment(calendarTime).add({ h: 1 }).calendar(), + '今天13:00', + 'Now plus 1 hour' + ); + assert.equal( + moment(calendarTime).add({ d: 1 }).calendar(), + '明天12:00', + 'tomorrow at the same time' + ); + assert.equal( + moment(calendarTime).subtract({ h: 1 }).calendar(), + '今天11:00', + 'Now minus 1 hour' + ); + assert.equal( + moment(calendarTime).subtract({ d: 1 }).calendar(), + '昨天12:00', + 'yesterday at the same time' + ); + }); + + describe('calendar next week', () => { + let i; + let m; + + for (i = 2; i < 7; i += 1) { + const week = moment().week(); + m = moment().add({ d: i }); + if (week === m.week()) { + assert.equal( + m.calendar(), + m.format('[本]dddLT'), + `Today + ${i} days current time` + ); + m.hours(0).minutes(0).seconds(0).milliseconds(0); + assert.equal( + m.calendar(), + m.format('[本]dddLT'), + `Today + ${i} days beginning of day` + ); + m.hours(23).minutes(59).seconds(59).milliseconds(999); + assert.equal( + m.calendar(), + m.format('[本]dddLT'), + `Today + ${i} days end of day` + ); + } else { + assert.equal( + m.calendar(), + m.format('[下]dddLT'), + `Today + ${i} days current time` + ); + m.hours(0).minutes(0).seconds(0).milliseconds(0); + assert.equal( + m.calendar(), + m.format('[下]dddLT'), + `Today + ${i} days beginning of day` + ); + m.hours(23).minutes(59).seconds(59).milliseconds(999); + assert.equal( + m.calendar(), + m.format('[下]dddLT'), + `Today + ${i} days end of day` + ); + } + } + }); + + describe('calendar last week', () => { + let i; + let m; + + for (i = 2; i < 7; i += 1) { + const week = moment().week(); + m = moment().subtract({ d: i }); + if (week !== m.week()) { + assert.equal( + m.calendar(), + m.format('[上]dddLT'), + `Today - ${i} days current time` + ); + m.hours(0).minutes(0).seconds(0).milliseconds(0); + assert.equal( + m.calendar(), + m.format('[上]dddLT'), + `Today - ${i} days beginning of day` + ); + m.hours(23).minutes(59).seconds(59).milliseconds(999); + assert.equal( + m.calendar(), + m.format('[上]dddLT'), + `Today - ${i} days end of day` + ); + } else { + assert.equal( + m.calendar(), + m.format('[本]dddLT'), + `Today - ${i} days current time` + ); + m.hours(0).minutes(0).seconds(0).milliseconds(0); + assert.equal( + m.calendar(), + m.format('[本]dddLT'), + `Today - ${i} days beginning of day` + ); + m.hours(23).minutes(59).seconds(59).milliseconds(999); + assert.equal( + m.calendar(), + m.format('[本]dddLT'), + `Today - ${i} days end of day` + ); + } + } + }); + + describe('calendar all else', () => { + let weeksAgo = moment().subtract({ w: 1 }); + let weeksFromNow = moment().add({ w: 1 }); + + assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago'); + assert.equal( + weeksFromNow.calendar(), + weeksFromNow.format('L'), + 'in 1 week' + ); + + weeksAgo = moment().subtract({ w: 2 }); + weeksFromNow = moment().add({ w: 2 }); + + assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago'); + assert.equal( + weeksFromNow.calendar(), + weeksFromNow.format('L'), + 'in 2 weeks' + ); + }); + + describe('weeks year starting sunday formatted', () => { + assert.equal( + moment([2012, 0, 1]).format('w ww wo'), + '52 52 52周', + 'Jan 1 2012 应该是第52周' + ); + assert.equal( + moment([2012, 0, 7]).format('w ww wo'), + '1 01 1周', + 'Jan 7 2012 应该是第 1周' + ); + assert.equal( + moment([2012, 0, 14]).format('w ww wo'), + '2 02 2周', + 'Jan 14 2012 应该是第 2周' + ); + }); +}); From 1a4c513f15bb8e1aa0aa4429ca7f95dfa5d9f8dd Mon Sep 17 00:00:00 2001 From: Karina Thomas Date: Mon, 28 Oct 2024 17:49:13 +0000 Subject: [PATCH 03/11] Update link to zh-cn tests --- src/app/legacy/psammead/psammead-locales/moment/zh-cn.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/legacy/psammead/psammead-locales/moment/zh-cn.test.js b/src/app/legacy/psammead/psammead-locales/moment/zh-cn.test.js index 3e9eb468252..c8fda13bb02 100644 --- a/src/app/legacy/psammead/psammead-locales/moment/zh-cn.test.js +++ b/src/app/legacy/psammead/psammead-locales/moment/zh-cn.test.js @@ -5,7 +5,7 @@ moment.locale('zh-cn'); // This asset overrides the gunit assertion done in the moment codebase. // Format and styling of this file has been keep consistent with the official moment tests. -// An example of these tests can be seen at https://github.com/moment/moment/blob/develop/src/test/locale/en-gb.js +// An example of these tests can be seen at https://github.com/moment/moment/blob/develop/src/test/locale/zh-cn.js const assert = { equal: (val1, val2, scenario) => it(scenario, () => expect(val1).toEqual(val2)), From 55039941881e08a10c7080d1dd605dec759def76 Mon Sep 17 00:00:00 2001 From: Karina Thomas Date: Tue, 29 Oct 2024 09:48:17 +0000 Subject: [PATCH 04/11] Add moment override to zhongwen service --- src/app/lib/config/services/zhongwen.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/lib/config/services/zhongwen.ts b/src/app/lib/config/services/zhongwen.ts index fc73e491137..d8cd16af4e1 100644 --- a/src/app/lib/config/services/zhongwen.ts +++ b/src/app/lib/config/services/zhongwen.ts @@ -1,6 +1,6 @@ import noAscendersOrDescenders from '../../../components/ThemeProvider/fontScripts/noAscOrDesc'; import '#psammead/moment-timezone-include/tz/GMT'; -import 'moment/locale/zh-cn'; +import '#psammead/psammead-locales/moment/zh-cn'; import withContext from '../../../contexts/utils/withContext'; import { ZhongwenConfig } from '../../../models/types/serviceConfig'; import { Direction, Services } from '../../../models/types/global'; From 5305f58eef0a1fa9e32eaff29c908eebf19d144c Mon Sep 17 00:00:00 2001 From: Karina Thomas Date: Tue, 29 Oct 2024 09:48:39 +0000 Subject: [PATCH 05/11] Customise the long date format for zhongwen --- src/app/legacy/psammead/psammead-locales/moment/zh-cn.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/app/legacy/psammead/psammead-locales/moment/zh-cn.js b/src/app/legacy/psammead/psammead-locales/moment/zh-cn.js index c02e6d5b1b8..8b973282d84 100644 --- a/src/app/legacy/psammead/psammead-locales/moment/zh-cn.js +++ b/src/app/legacy/psammead/psammead-locales/moment/zh-cn.js @@ -2,6 +2,9 @@ const moment = require('moment'); require('moment/locale/zh-cn'); moment.updateLocale('zh-cn', { + longDateFormat: { + LLL: 'YYYY年M月D日Ah時mm分', + }, relativeTime: { // these keys have been overridden with our translations // some other keys have been left as set upstream From ccb8cebcc58c895a90249231027ef43e1d2c5e8b Mon Sep 17 00:00:00 2001 From: Karina Thomas Date: Tue, 29 Oct 2024 13:01:51 +0000 Subject: [PATCH 06/11] Rename zh-cn to zh-tw --- .../psammead-locales/moment/{zh-cn.js => zh-tw.js} | 7 ++++--- .../moment/{zh-cn.test.js => zh-tw.test.js} | 8 ++++---- 2 files changed, 8 insertions(+), 7 deletions(-) rename src/app/legacy/psammead/psammead-locales/moment/{zh-cn.js => zh-tw.js} (78%) rename src/app/legacy/psammead/psammead-locales/moment/{zh-cn.test.js => zh-tw.test.js} (99%) diff --git a/src/app/legacy/psammead/psammead-locales/moment/zh-cn.js b/src/app/legacy/psammead/psammead-locales/moment/zh-tw.js similarity index 78% rename from src/app/legacy/psammead/psammead-locales/moment/zh-cn.js rename to src/app/legacy/psammead/psammead-locales/moment/zh-tw.js index 8b973282d84..b39c08a37bb 100644 --- a/src/app/legacy/psammead/psammead-locales/moment/zh-cn.js +++ b/src/app/legacy/psammead/psammead-locales/moment/zh-tw.js @@ -1,14 +1,15 @@ const moment = require('moment'); -require('moment/locale/zh-cn'); +require('moment/locale/zh-tw'); -moment.updateLocale('zh-cn', { +moment.updateLocale('zh-tw', { longDateFormat: { + LL: 'YYYY年M月D日', LLL: 'YYYY年M月D日Ah時mm分', }, relativeTime: { // these keys have been overridden with our translations // some other keys have been left as set upstream - // see https://github.com/moment/moment/blob/develop/src/locale/zh-cn.js + // see https://github.com/moment/moment/blob/develop/src/locale/zh-tw.js m: '1 分鐘', mm: '%d 分鐘', h: '1 小時', diff --git a/src/app/legacy/psammead/psammead-locales/moment/zh-cn.test.js b/src/app/legacy/psammead/psammead-locales/moment/zh-tw.test.js similarity index 99% rename from src/app/legacy/psammead/psammead-locales/moment/zh-cn.test.js rename to src/app/legacy/psammead/psammead-locales/moment/zh-tw.test.js index c8fda13bb02..b74c4d9cb63 100644 --- a/src/app/legacy/psammead/psammead-locales/moment/zh-cn.test.js +++ b/src/app/legacy/psammead/psammead-locales/moment/zh-tw.test.js @@ -1,7 +1,7 @@ import moment from 'moment'; -import './zh-cn'; +import './zh-tw'; -moment.locale('zh-cn'); +moment.locale('zh-tw'); // This asset overrides the gunit assertion done in the moment codebase. // Format and styling of this file has been keep consistent with the official moment tests. @@ -11,7 +11,7 @@ const assert = { it(scenario, () => expect(val1).toEqual(val2)), }; -describe('zh-cn', () => { +describe('zh-tw', () => { describe('parse', () => { const tests = '一月 1月_二月 2月_三月 3月_四月 4月_五月 5月_六月 6月_七月 7月_八月 8月_九月 9月_十月 10月_十一月 11月_十二月 12月'.split( @@ -58,7 +58,7 @@ describe('zh-cn', () => { ['LTS', '15:25:50'], ['L', '2010/02/14'], ['LL', '2010年2月14日'], - ['LLL', '2010年2月14日下午3点25分'], + ['LLL', '2010年2月14日下午3時25分'], ['LLLL', '2010年2月14日星期日下午3点25分'], ['l', '2010/2/14'], ['ll', '2010年2月14日'], From 12867c891205049f22fdd124e064b6cb75b3efbc Mon Sep 17 00:00:00 2001 From: Karina Thomas Date: Tue, 29 Oct 2024 13:02:08 +0000 Subject: [PATCH 07/11] Add zh-tw to the list of locales with long datetime locales --- src/app/legacy/containers/ArticleTimestamp/timeFormats.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/legacy/containers/ArticleTimestamp/timeFormats.js b/src/app/legacy/containers/ArticleTimestamp/timeFormats.js index 658c9d3f543..7208a7b4721 100644 --- a/src/app/legacy/containers/ArticleTimestamp/timeFormats.js +++ b/src/app/legacy/containers/ArticleTimestamp/timeFormats.js @@ -1,7 +1,7 @@ // 2019-03-22 export const formatDateNumeric = 'YYYY-MM-DD'; -const longDatetimeLocales = ['ja', 'ko', 'zh-cn']; +const longDatetimeLocales = ['ja', 'ko', 'zh-cn', 'zh-tw']; // 22 March 2019 export const formatDate = datetimeLocale => { From 1733e52051839b602171cca959e3809f08674b66 Mon Sep 17 00:00:00 2001 From: Karina Thomas Date: Tue, 29 Oct 2024 13:02:40 +0000 Subject: [PATCH 08/11] Use separate locales for zhongwen trad & simp --- src/app/lib/config/services/zhongwen.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/app/lib/config/services/zhongwen.ts b/src/app/lib/config/services/zhongwen.ts index d8cd16af4e1..fed3d0c7db9 100644 --- a/src/app/lib/config/services/zhongwen.ts +++ b/src/app/lib/config/services/zhongwen.ts @@ -1,6 +1,7 @@ import noAscendersOrDescenders from '../../../components/ThemeProvider/fontScripts/noAscOrDesc'; import '#psammead/moment-timezone-include/tz/GMT'; -import '#psammead/psammead-locales/moment/zh-cn'; +import 'moment/locale/zh-cn'; +import '#psammead/psammead-locales/moment/zh-tw'; import withContext from '../../../contexts/utils/withContext'; import { ZhongwenConfig } from '../../../models/types/serviceConfig'; import { Direction, Services } from '../../../models/types/global'; @@ -18,7 +19,6 @@ const baseServiceConfig = { defaultImage: 'https://news.files.bbci.co.uk/ws/img/logos/og/zhongwen.png', defaultImageAltText: 'BBC News 中文', dir: 'ltr' as Direction, - datetimeLocale: `zh-cn`, service: 'zhongwen' as Services, serviceName: 'News 中文', languageName: 'Chinese', @@ -63,6 +63,7 @@ export const service: ZhongwenConfig = { locale: `zh-hans`, // valid ISO 639-1 code - this is not the same as lang! see explanation in #3405 isoLang: 'zh-Hans', + datetimeLocale: 'zh-cn', defaultCaptionOffscreenText: '说明文字,', audioCaptionOffscreenText: '音频加注文字,', videoCaptionOffscreenText: '视频加注文字,', @@ -361,6 +362,7 @@ export const service: ZhongwenConfig = { locale: `zh-hant`, // valid ISO 639-1 code - this is not the same as lang! see explanation in #3405 isoLang: 'zh-Hant', + datetimeLocale: 'zh-tw', externalLinkText: ', 外部', frontPageTitle: '主頁', defaultCaptionOffscreenText: '說明文字,', From 07724974909e1442d4b330fefb54e9ddc495c3e5 Mon Sep 17 00:00:00 2001 From: Karina Thomas Date: Tue, 29 Oct 2024 13:20:56 +0000 Subject: [PATCH 09/11] Fix tests for zh-tw --- .../psammead-locales/moment/zh-tw.test.js | 187 +++++++----------- 1 file changed, 75 insertions(+), 112 deletions(-) diff --git a/src/app/legacy/psammead/psammead-locales/moment/zh-tw.test.js b/src/app/legacy/psammead/psammead-locales/moment/zh-tw.test.js index b74c4d9cb63..80e76487908 100644 --- a/src/app/legacy/psammead/psammead-locales/moment/zh-tw.test.js +++ b/src/app/legacy/psammead/psammead-locales/moment/zh-tw.test.js @@ -42,24 +42,24 @@ describe('zh-tw', () => { const a = [ ['dddd, MMMM Do YYYY, a h:mm:ss', '星期日, 二月 14日 2010, 下午 3:25:50'], - ['ddd, Ah', '周日, 下午3'], + ['ddd, Ah', '週日, 下午3'], ['M Mo MM MMMM MMM', '2 2月 02 二月 2月'], ['YYYY YY', '2010 10'], ['D Do DD', '14 14日 14'], - ['d do dddd ddd dd', '0 0日 星期日 周日 日'], + ['d do dddd ddd dd', '0 0日 星期日 週日 日'], ['DDD DDDo DDDD', '45 45日 045'], - ['w wo ww', '6 6周 06'], + ['w wo ww', '8 8週 08'], ['h hh', '3 03'], ['H HH', '15 15'], ['m mm', '25 25'], ['s ss', '50 50'], ['a A', '下午 下午'], - ['[这年的第] DDDo', '这年的第 45日'], + ['[這年的第] DDDo', '這年的第 45日'], ['LTS', '15:25:50'], ['L', '2010/02/14'], ['LL', '2010年2月14日'], ['LLL', '2010年2月14日下午3時25分'], - ['LLLL', '2010年2月14日星期日下午3点25分'], + ['LLLL', '2010年2月14日星期日 15:25'], ['l', '2010/2/14'], ['ll', '2010年2月14日'], ['lll', '2010年2月14日 15:25'], @@ -129,7 +129,7 @@ describe('zh-tw', () => { describe('format week', () => { const expected = - '星期日 周日 日_星期一 周一 一_星期二 周二 二_星期三 周三 三_星期四 周四 四_星期五 周五 五_星期六 周六 六'.split( + '星期日 週日 日_星期一 週一 一_星期二 週二 二_星期三 週三 三_星期四 週四 四_星期五 週五 五_星期六 週六 六'.split( '_' ); let i; @@ -144,11 +144,6 @@ describe('zh-tw', () => { describe('from', () => { const start = moment([2007, 1, 28]); - assert.equal( - start.from(moment([2007, 1, 28]).add({ s: 44 }), true), - '几秒', - '44 seconds = a few seconds' - ); assert.equal( start.from(moment([2007, 1, 28]).add({ s: 45 }), true), '1 分鐘', @@ -226,42 +221,42 @@ describe('zh-tw', () => { ); assert.equal( start.from(moment([2007, 1, 28]).add({ d: 26 }), true), - '1 个月', + '1 個月', '26 days = a month' ); assert.equal( start.from(moment([2007, 1, 28]).add({ d: 30 }), true), - '1 个月', + '1 個月', '30 days = a month' ); assert.equal( start.from(moment([2007, 1, 28]).add({ d: 43 }), true), - '1 个月', + '1 個月', '43 days = a month' ); assert.equal( start.from(moment([2007, 1, 28]).add({ d: 46 }), true), - '2 个月', + '2 個月', '46 days = 2 months' ); assert.equal( start.from(moment([2007, 1, 28]).add({ d: 74 }), true), - '2 个月', + '2 個月', '75 days = 2 months' ); assert.equal( start.from(moment([2007, 1, 28]).add({ d: 76 }), true), - '3 个月', + '3 個月', '76 days = 3 months' ); assert.equal( start.from(moment([2007, 1, 28]).add({ M: 1 }), true), - '1 个月', + '1 個月', '1 month = a month' ); assert.equal( start.from(moment([2007, 1, 28]).add({ M: 5 }), true), - '5 个月', + '5 個月', '5 months = 5 months' ); assert.equal( @@ -287,14 +282,14 @@ describe('zh-tw', () => { }); describe('suffix', () => { - assert.equal(moment(30000).from(0), '几秒后', 'prefix'); - assert.equal(moment(0).from(30000), '几秒前', 'prefix'); + assert.equal(moment(30000).from(0), '幾秒後', 'prefix'); + assert.equal(moment(0).from(30000), '幾秒前', 'prefix'); }); describe('now from now', () => { assert.equal( moment().fromNow(), - '几秒前', + '幾秒前', 'now from now should display as in the past' ); }); @@ -302,10 +297,10 @@ describe('zh-tw', () => { describe('fromNow', () => { assert.equal( moment().add({ s: 30 }).fromNow(), - '几秒后', + '幾秒後', 'in a few seconds' ); - assert.equal(moment().add({ d: 5 }).fromNow(), '5 天后', 'in 5 days'); + assert.equal(moment().add({ d: 5 }).fromNow(), '5 天後', 'in 5 days'); }); describe('calendar day', () => { @@ -313,32 +308,32 @@ describe('zh-tw', () => { assert.equal( moment(calendarTime).calendar(), - '今天12:00', + '今天 12:00', 'today at the same time' ); assert.equal( moment(calendarTime).add({ m: 25 }).calendar(), - '今天12:25', + '今天 12:25', 'Now plus 25 min' ); assert.equal( moment(calendarTime).add({ h: 1 }).calendar(), - '今天13:00', + '今天 13:00', 'Now plus 1 hour' ); assert.equal( moment(calendarTime).add({ d: 1 }).calendar(), - '明天12:00', + '明天 12:00', 'tomorrow at the same time' ); assert.equal( moment(calendarTime).subtract({ h: 1 }).calendar(), - '今天11:00', + '今天 11:00', 'Now minus 1 hour' ); assert.equal( moment(calendarTime).subtract({ d: 1 }).calendar(), - '昨天12:00', + '昨天 12:00', 'yesterday at the same time' ); }); @@ -348,45 +343,24 @@ describe('zh-tw', () => { let m; for (i = 2; i < 7; i += 1) { - const week = moment().week(); m = moment().add({ d: i }); - if (week === m.week()) { - assert.equal( - m.calendar(), - m.format('[本]dddLT'), - `Today + ${i} days current time` - ); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - assert.equal( - m.calendar(), - m.format('[本]dddLT'), - `Today + ${i} days beginning of day` - ); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - assert.equal( - m.calendar(), - m.format('[本]dddLT'), - `Today + ${i} days end of day` - ); - } else { - assert.equal( - m.calendar(), - m.format('[下]dddLT'), - `Today + ${i} days current time` - ); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - assert.equal( - m.calendar(), - m.format('[下]dddLT'), - `Today + ${i} days beginning of day` - ); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - assert.equal( - m.calendar(), - m.format('[下]dddLT'), - `Today + ${i} days end of day` - ); - } + assert.equal( + m.calendar(), + m.format('[下]dddd LT'), + `Today + ${i} days current time` + ); + m.hours(0).minutes(0).seconds(0).milliseconds(0); + assert.equal( + m.calendar(), + m.format('[下]dddd LT'), + `Today + ${i} days beginning of day` + ); + m.hours(23).minutes(59).seconds(59).milliseconds(999); + assert.equal( + m.calendar(), + m.format('[下]dddd LT'), + `Today + ${i} days end of day` + ); } }); @@ -395,45 +369,24 @@ describe('zh-tw', () => { let m; for (i = 2; i < 7; i += 1) { - const week = moment().week(); m = moment().subtract({ d: i }); - if (week !== m.week()) { - assert.equal( - m.calendar(), - m.format('[上]dddLT'), - `Today - ${i} days current time` - ); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - assert.equal( - m.calendar(), - m.format('[上]dddLT'), - `Today - ${i} days beginning of day` - ); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - assert.equal( - m.calendar(), - m.format('[上]dddLT'), - `Today - ${i} days end of day` - ); - } else { - assert.equal( - m.calendar(), - m.format('[本]dddLT'), - `Today - ${i} days current time` - ); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - assert.equal( - m.calendar(), - m.format('[本]dddLT'), - `Today - ${i} days beginning of day` - ); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - assert.equal( - m.calendar(), - m.format('[本]dddLT'), - `Today - ${i} days end of day` - ); - } + assert.equal( + m.calendar(), + m.format('[上]dddd LT'), + `Today - ${i} days current time` + ); + m.hours(0).minutes(0).seconds(0).milliseconds(0); + assert.equal( + m.calendar(), + m.format('[上]dddd LT'), + `Today - ${i} days beginning of day` + ); + m.hours(23).minutes(59).seconds(59).milliseconds(999); + assert.equal( + m.calendar(), + m.format('[上]dddd LT'), + `Today - ${i} days end of day` + ); } }); @@ -462,18 +415,28 @@ describe('zh-tw', () => { describe('weeks year starting sunday formatted', () => { assert.equal( moment([2012, 0, 1]).format('w ww wo'), - '52 52 52周', - 'Jan 1 2012 应该是第52周' + '1 01 1週', + 'Jan 1 2012 應該是第 1週' ); assert.equal( moment([2012, 0, 7]).format('w ww wo'), - '1 01 1周', - 'Jan 7 2012 应该是第 1周' + '1 01 1週', + 'Jan 7 2012 應該是第 1週' + ); + assert.equal( + moment([2012, 0, 8]).format('w ww wo'), + '2 02 2週', + 'Jan 8 2012 應該是第 2週' ); assert.equal( moment([2012, 0, 14]).format('w ww wo'), - '2 02 2周', - 'Jan 14 2012 应该是第 2周' + '2 02 2週', + 'Jan 14 2012 應該是第 2週' + ); + assert.equal( + moment([2012, 0, 15]).format('w ww wo'), + '3 03 3週', + 'Jan 15 2012 應該是第 3週' ); }); }); From cfa4b364cd5b890cb859b6600996704a994ac893 Mon Sep 17 00:00:00 2001 From: Karina Thomas Date: Tue, 29 Oct 2024 16:40:48 +0000 Subject: [PATCH 10/11] Fix typo --- src/app/legacy/psammead/psammead-locales/moment/zh-tw.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/legacy/psammead/psammead-locales/moment/zh-tw.test.js b/src/app/legacy/psammead/psammead-locales/moment/zh-tw.test.js index 80e76487908..2caf57ec09e 100644 --- a/src/app/legacy/psammead/psammead-locales/moment/zh-tw.test.js +++ b/src/app/legacy/psammead/psammead-locales/moment/zh-tw.test.js @@ -3,7 +3,7 @@ import './zh-tw'; moment.locale('zh-tw'); -// This asset overrides the gunit assertion done in the moment codebase. +// This assert overrides the gunit assertion done in the moment codebase. // Format and styling of this file has been keep consistent with the official moment tests. // An example of these tests can be seen at https://github.com/moment/moment/blob/develop/src/test/locale/zh-cn.js const assert = { From 90832452f62563469557cc047761fa620b8e8253 Mon Sep 17 00:00:00 2001 From: Karina Thomas Date: Tue, 29 Oct 2024 16:43:11 +0000 Subject: [PATCH 11/11] Update link to moment source test file --- src/app/legacy/psammead/psammead-locales/moment/zh-tw.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/legacy/psammead/psammead-locales/moment/zh-tw.test.js b/src/app/legacy/psammead/psammead-locales/moment/zh-tw.test.js index 2caf57ec09e..3f152487752 100644 --- a/src/app/legacy/psammead/psammead-locales/moment/zh-tw.test.js +++ b/src/app/legacy/psammead/psammead-locales/moment/zh-tw.test.js @@ -5,7 +5,7 @@ moment.locale('zh-tw'); // This assert overrides the gunit assertion done in the moment codebase. // Format and styling of this file has been keep consistent with the official moment tests. -// An example of these tests can be seen at https://github.com/moment/moment/blob/develop/src/test/locale/zh-cn.js +// An example of these tests can be seen at https://github.com/moment/moment/blob/develop/src/test/locale/zh-tw.js const assert = { equal: (val1, val2, scenario) => it(scenario, () => expect(val1).toEqual(val2)),