-
-
Notifications
You must be signed in to change notification settings - Fork 194
Expand file tree
/
Copy pathLocalizationUtils.js
More file actions
147 lines (130 loc) · 6.24 KB
/
LocalizationUtils.js
File metadata and controls
147 lines (130 loc) · 6.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/*
* GNU AGPL-3.0 License
*
* Copyright (c) 2021 - present core.ai . All rights reserved.
* Original work Copyright (c) 2014 - 2021 Adobe Systems Incorporated. All rights reserved.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License
* for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see https://opensource.org/licenses/AGPL-3.0.
*
*/
// @INCLUDE_IN_API_DOCS
define(function (require, exports, module) {
const Strings = require("strings");
/**
* Converts a language code to its written name, if possible.
* If not possible, the language code is simply returned.
*
* @param {string} locale The two-char language code
* @return {string} The language's name or the given language code
*/
function getLocalizedLabel(locale) {
var key = "LOCALE_" + locale.toUpperCase().replace("-", "_"),
i18n = Strings[key];
return i18n === undefined ? locale : i18n;
}
const DATE_TIME_STYLE = {
FULL: "full",
LONG: "long",
MEDIUM: "medium",
SHORT: "short"
};
/**
* Formats a given date object into a locale-aware date and time string.
*
* @param {Date} [date] - The date object to format. If not provided, the current date and time will be used.
* @param {string} [lang] - Optional language code to use for formatting (e.g., 'en', 'fr').
* If not provided, defaults to the application locale or 'en'.
* @param {Object} [dateTimeFormat] - Optional object specifying the date and time formatting options.
* Defaults to { dateStyle: 'medium', timeStyle: 'short' }.
* @param {string} [dateTimeFormat.dateStyle] - Specifies the date format style. One of: DATE_TIME_STYLE.*
* @param {string} [dateTimeFormat.timeStyle] - Specifies the time format style. One of: DATE_TIME_STYLE.*
* @returns {string} - The formatted date and time string (e.g., "Dec 24, 2024, 10:30 AM").
*/
function getFormattedDateTime(date, lang, dateTimeFormat) {
if(!date){
date = new Date();
}
if(!dateTimeFormat){
dateTimeFormat = {
dateStyle: DATE_TIME_STYLE.MEDIUM,
timeStyle: DATE_TIME_STYLE.SHORT
};
}
return Intl.DateTimeFormat([lang || brackets.getLocale() || "en", "en"], dateTimeFormat).format(date);
}
/**
* Returns a relative time string (e.g., "2 days ago", "in 3 hours") based on the difference between the given date and now.
*
* @param {Date} [date] - The date to compare with the current date and time. If not given, defaults to now.
* @param {string} [lang] - Optional language code to use for formatting (e.g., 'en', 'fr').
* If not provided, defaults to the application locale or 'en'.
* @returns {string} - A human-readable relative time string (e.g., "2 days ago", "in 3 hours").
*/
function dateTimeFromNow(date, lang) {
date = date || new Date();
const now = new Date();
const diffInSeconds = Math.floor((date - now) / 1000);
const rtf = new Intl.RelativeTimeFormat([lang || brackets.getLocale() || "en", "en"],
{ numeric: 'auto' });
if (Math.abs(diffInSeconds) < 60) {
return rtf.format(diffInSeconds, 'second');
} else if (Math.abs(diffInSeconds) < 3600) {
return rtf.format(Math.floor(diffInSeconds / 60), 'minute');
} else if (Math.abs(diffInSeconds) < 86400) {
return rtf.format(Math.floor(diffInSeconds / 3600), 'hour');
} else if (Math.abs(diffInSeconds) < 2592000) {
return rtf.format(Math.floor(diffInSeconds / 86400), 'day');
} else if (Math.abs(diffInSeconds) < 31536000) {
return rtf.format(Math.floor(diffInSeconds / 2592000), 'month');
} else {
return rtf.format(Math.floor(diffInSeconds / 31536000), 'year');
}
}
/**
* Returns an intelligent date string.
* - For dates within the last 30 days or the future: relative time (e.g., "2 days ago", "in 3 hours").
* - For dates earlier this year: formatted date (e.g., "Jan 5").
* - For dates not in the current year: formatted date with year (e.g., "Jan 5, 2023").
*
* @param {Date} date - The date to compare and format.
* @param {string} [lang] - Optional language code to use for formatting (e.g., 'en', 'fr').
* @returns {string} - An intelligently formatted date string.
*/
function dateTimeFromNowFriendly(date, lang) {
const now = new Date();
const diffInMilliseconds = date - now;
const diffInDays = Math.floor(diffInMilliseconds / (1000 * 60 * 60 * 24));
// If within the last 30 days or the future, use relative time
if (Math.abs(diffInDays) <= 30) {
return dateTimeFromNow(date, lang);
}
// If in the current year, format as "MMM DD"
const currentYear = now.getFullYear();
const dateYear = date.getFullYear();
const languageOption = [lang || brackets.getLocale() || "en", "en"];
if (currentYear === dateYear) {
return new Intl.DateTimeFormat(languageOption, { month: "short", day: "numeric" }).format(date);
}
// For dates in previous years, format as "MMM DD, YYYY"
return new Intl.DateTimeFormat(languageOption,
{ month: "short", day: "numeric", year: "numeric" }).format(date);
}
// Define public API
exports.getLocalizedLabel = getLocalizedLabel;
exports.getFormattedDateTime = getFormattedDateTime;
exports.dateTimeFromNow = dateTimeFromNow;
exports.dateTimeFromNowFriendly = dateTimeFromNowFriendly;
// public constants
exports.DATE_TIME_STYLE = DATE_TIME_STYLE;
});