mirror of
https://github.com/louislam/uptime-kuma.git
synced 2025-09-10 12:56:13 +08:00
Compare commits
26 Commits
1.19.0-bet
...
1.19.2
Author | SHA1 | Date | |
---|---|---|---|
|
aec80b53d5 | ||
|
06852bbf0d | ||
|
056d957c1e | ||
|
e12225e595 | ||
|
1b6c587cc9 | ||
|
4a1db336df | ||
|
9e9c5cd1d2 | ||
|
1e689d99b4 | ||
|
14fffcf06b | ||
|
6962e056ce | ||
|
b7a898326e | ||
|
a89be0e6d4 | ||
|
b58b83541b | ||
|
df4f91c20d | ||
|
fc6b040a4e | ||
|
9838f36b50 | ||
|
a60072adbc | ||
|
e7aeb6f6bf | ||
|
06e570c52d | ||
|
890b8f8333 | ||
|
df21f7da76 | ||
|
20c37a70f7 | ||
|
b75db27658 | ||
|
765d8e1297 | ||
|
9dc2cc1f0d | ||
|
f32441e2f6 |
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "uptime-kuma",
|
||||
"version": "1.19.0-beta.2",
|
||||
"version": "1.19.2",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -38,7 +38,7 @@
|
||||
"build-docker-nightly-amd64": "docker buildx build -f docker/dockerfile --platform linux/amd64 -t louislam/uptime-kuma:nightly-amd64 --target nightly . --push --progress plain",
|
||||
"build-docker-pr-test": "docker buildx build -f docker/dockerfile --platform linux/amd64,linux/arm64 -t louislam/uptime-kuma:pr-test --target pr-test . --push",
|
||||
"upload-artifacts": "docker buildx build -f docker/dockerfile --platform linux/amd64 -t louislam/uptime-kuma:upload-artifact --build-arg VERSION --build-arg GITHUB_TOKEN --target upload-artifact . --progress plain",
|
||||
"setup": "git checkout 1.18.5 && npm ci --production && npm run download-dist",
|
||||
"setup": "git checkout 1.19.2 && npm ci --production && npm run download-dist",
|
||||
"download-dist": "node extra/download-dist.js",
|
||||
"mark-as-nightly": "node extra/mark-as-nightly.js",
|
||||
"reset-password": "node extra/reset-password.js",
|
||||
|
@@ -16,7 +16,6 @@ const { CacheableDnsHttpAgent } = require("../cacheable-dns-http-agent");
|
||||
const { DockerHost } = require("../docker");
|
||||
const Maintenance = require("./maintenance");
|
||||
const { UptimeCacheList } = require("../uptime-cache-list");
|
||||
const zlib = require("zlib");
|
||||
|
||||
/**
|
||||
* status:
|
||||
@@ -276,9 +275,6 @@ class Monitor extends BeanModel {
|
||||
...(this.body ? { data: JSON.parse(this.body) } : {}),
|
||||
timeout: this.interval * 1000 * 0.8,
|
||||
headers: {
|
||||
// Fix #2253
|
||||
// Read more: https://stackoverflow.com/questions/1759956/curl-error-18-transfer-closed-with-outstanding-read-data-remaining
|
||||
"Accept-Encoding": "gzip, deflate",
|
||||
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
|
||||
"User-Agent": "Uptime-Kuma/" + version,
|
||||
...(this.headers ? JSON.parse(this.headers) : {}),
|
||||
@@ -311,20 +307,8 @@ class Monitor extends BeanModel {
|
||||
log.debug("monitor", `[${this.name}] Axios Options: ${JSON.stringify(options)}`);
|
||||
log.debug("monitor", `[${this.name}] Axios Request`);
|
||||
|
||||
let res;
|
||||
if (this.auth_method === "ntlm") {
|
||||
options.httpsAgent.keepAlive = true;
|
||||
|
||||
res = await httpNtlm(options, {
|
||||
username: this.basic_auth_user,
|
||||
password: this.basic_auth_pass,
|
||||
domain: this.authDomain,
|
||||
workstation: this.authWorkstation ? this.authWorkstation : undefined
|
||||
});
|
||||
|
||||
} else {
|
||||
res = await axios.request(options);
|
||||
}
|
||||
// Make Request
|
||||
let res = await this.makeAxiosRequest(options);
|
||||
|
||||
bean.msg = `${res.status} - ${res.statusText}`;
|
||||
bean.ping = dayjs().valueOf() - startTime;
|
||||
@@ -762,6 +746,40 @@ class Monitor extends BeanModel {
|
||||
}
|
||||
}
|
||||
|
||||
async makeAxiosRequest(options, finalCall = false) {
|
||||
try {
|
||||
let res;
|
||||
if (this.auth_method === "ntlm") {
|
||||
options.httpsAgent.keepAlive = true;
|
||||
|
||||
res = await httpNtlm(options, {
|
||||
username: this.basic_auth_user,
|
||||
password: this.basic_auth_pass,
|
||||
domain: this.authDomain,
|
||||
workstation: this.authWorkstation ? this.authWorkstation : undefined
|
||||
});
|
||||
|
||||
} else {
|
||||
res = await axios.request(options);
|
||||
}
|
||||
|
||||
return res;
|
||||
} catch (e) {
|
||||
// Fix #2253
|
||||
// Read more: https://stackoverflow.com/questions/1759956/curl-error-18-transfer-closed-with-outstanding-read-data-remaining
|
||||
if (!finalCall && typeof e.message === "string" && e.message.includes("maxContentLength size of -1 exceeded")) {
|
||||
log.debug("monitor", "makeAxiosRequest with gzip");
|
||||
options.headers["Accept-Encoding"] = "gzip, deflate";
|
||||
return this.makeAxiosRequest(options, true);
|
||||
} else {
|
||||
if (typeof e.message === "string" && e.message.includes("maxContentLength size of -1 exceeded")) {
|
||||
e.message = "response timeout: incomplete response within a interval";
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Stop monitor */
|
||||
stop() {
|
||||
clearTimeout(this.heartbeatInterval);
|
||||
@@ -1069,7 +1087,13 @@ class Monitor extends BeanModel {
|
||||
|
||||
for (let notification of notificationList) {
|
||||
try {
|
||||
await Notification.send(JSON.parse(notification.config), msg, await monitor.toJSON(false), bean.toJSON());
|
||||
// Prevent if the msg is undefined, notifications such as Discord cannot send out.
|
||||
const heartbeatJSON = bean.toJSON();
|
||||
if (!heartbeatJSON["msg"]) {
|
||||
heartbeatJSON["msg"] = "";
|
||||
}
|
||||
|
||||
await Notification.send(JSON.parse(notification.config), msg, await monitor.toJSON(false), heartbeatJSON);
|
||||
} catch (e) {
|
||||
log.error("monitor", "Cannot send notification to " + notification.name);
|
||||
log.error("monitor", e);
|
||||
|
20
server/modules/dayjs/plugin/timezone.d.ts
vendored
Normal file
20
server/modules/dayjs/plugin/timezone.d.ts
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
import { PluginFunc, ConfigType } from 'dayjs'
|
||||
|
||||
declare const plugin: PluginFunc
|
||||
export = plugin
|
||||
|
||||
declare module 'dayjs' {
|
||||
interface Dayjs {
|
||||
tz(timezone?: string, keepLocalTime?: boolean): Dayjs
|
||||
offsetName(type?: 'short' | 'long'): string | undefined
|
||||
}
|
||||
|
||||
interface DayjsTimezone {
|
||||
(date: ConfigType, timezone?: string): Dayjs
|
||||
(date: ConfigType, format: string, timezone?: string): Dayjs
|
||||
guess(): string
|
||||
setDefault(timezone?: string): void
|
||||
}
|
||||
|
||||
const tz: DayjsTimezone
|
||||
}
|
115
server/modules/dayjs/plugin/timezone.js
Normal file
115
server/modules/dayjs/plugin/timezone.js
Normal file
@@ -0,0 +1,115 @@
|
||||
/**
|
||||
* Copy from node_modules/dayjs/plugin/timezone.js
|
||||
* Try to fix https://github.com/louislam/uptime-kuma/issues/2318
|
||||
* Source: https://github.com/iamkun/dayjs/tree/dev/src/plugin/utc
|
||||
* License: MIT
|
||||
*/
|
||||
!function (t, e) {
|
||||
// eslint-disable-next-line no-undef
|
||||
typeof exports == "object" && typeof module != "undefined" ? module.exports = e() : typeof define == "function" && define.amd ? define(e) : (t = typeof globalThis != "undefined" ? globalThis : t || self).dayjs_plugin_timezone = e();
|
||||
}(this, (function () {
|
||||
"use strict";
|
||||
let t = {
|
||||
year: 0,
|
||||
month: 1,
|
||||
day: 2,
|
||||
hour: 3,
|
||||
minute: 4,
|
||||
second: 5
|
||||
};
|
||||
let e = {};
|
||||
return function (n, i, o) {
|
||||
let r;
|
||||
let a = function (t, n, i) {
|
||||
void 0 === i && (i = {});
|
||||
let o = new Date(t);
|
||||
let r = function (t, n) {
|
||||
void 0 === n && (n = {});
|
||||
let i = n.timeZoneName || "short";
|
||||
let o = t + "|" + i;
|
||||
let r = e[o];
|
||||
return r || (r = new Intl.DateTimeFormat("en-US", {
|
||||
hour12: !1,
|
||||
timeZone: t,
|
||||
year: "numeric",
|
||||
month: "2-digit",
|
||||
day: "2-digit",
|
||||
hour: "2-digit",
|
||||
minute: "2-digit",
|
||||
second: "2-digit",
|
||||
timeZoneName: i
|
||||
}), e[o] = r), r;
|
||||
}(n, i);
|
||||
return r.formatToParts(o);
|
||||
};
|
||||
let u = function (e, n) {
|
||||
let i = a(e, n);
|
||||
let r = [];
|
||||
let u = 0;
|
||||
for (; u < i.length; u += 1) {
|
||||
let f = i[u];
|
||||
let s = f.type;
|
||||
let m = f.value;
|
||||
let c = t[s];
|
||||
c >= 0 && (r[c] = parseInt(m, 10));
|
||||
}
|
||||
let d = r[3];
|
||||
let l = d === 24 ? 0 : d;
|
||||
let v = r[0] + "-" + r[1] + "-" + r[2] + " " + l + ":" + r[4] + ":" + r[5] + ":000";
|
||||
let h = +e;
|
||||
return (o.utc(v).valueOf() - (h -= h % 1e3)) / 6e4;
|
||||
};
|
||||
let f = i.prototype;
|
||||
f.tz = function (t, e) {
|
||||
void 0 === t && (t = r);
|
||||
let n = this.utcOffset();
|
||||
let i = this.toDate();
|
||||
let a = i.toLocaleString("en-US", { timeZone: t }).replace("\u202f", " ");
|
||||
let u = Math.round((i - new Date(a)) / 1e3 / 60);
|
||||
let f = o(a).$set("millisecond", this.$ms).utcOffset(15 * -Math.round(i.getTimezoneOffset() / 15) - u, !0);
|
||||
if (e) {
|
||||
let s = f.utcOffset();
|
||||
f = f.add(n - s, "minute");
|
||||
}
|
||||
return f.$x.$timezone = t, f;
|
||||
}, f.offsetName = function (t) {
|
||||
let e = this.$x.$timezone || o.tz.guess();
|
||||
let n = a(this.valueOf(), e, { timeZoneName: t }).find((function (t) {
|
||||
return t.type.toLowerCase() === "timezonename";
|
||||
}));
|
||||
return n && n.value;
|
||||
};
|
||||
let s = f.startOf;
|
||||
f.startOf = function (t, e) {
|
||||
if (!this.$x || !this.$x.$timezone) {
|
||||
return s.call(this, t, e);
|
||||
}
|
||||
let n = o(this.format("YYYY-MM-DD HH:mm:ss:SSS"));
|
||||
return s.call(n, t, e).tz(this.$x.$timezone, !0);
|
||||
}, o.tz = function (t, e, n) {
|
||||
let i = n && e;
|
||||
let a = n || e || r;
|
||||
let f = u(+o(), a);
|
||||
if (typeof t != "string") {
|
||||
return o(t).tz(a);
|
||||
}
|
||||
let s = function (t, e, n) {
|
||||
let i = t - 60 * e * 1e3;
|
||||
let o = u(i, n);
|
||||
if (e === o) {
|
||||
return [ i, e ];
|
||||
}
|
||||
let r = u(i -= 60 * (o - e) * 1e3, n);
|
||||
return o === r ? [ i, o ] : [ t - 60 * Math.min(o, r) * 1e3, Math.max(o, r) ];
|
||||
}(o.utc(t, i).valueOf(), f, a);
|
||||
let m = s[0];
|
||||
let c = s[1];
|
||||
let d = o(m).utcOffset(c);
|
||||
return d.$x.$timezone = a, d;
|
||||
}, o.tz.guess = function () {
|
||||
return Intl.DateTimeFormat().resolvedOptions().timeZone;
|
||||
}, o.tz.setDefault = function (t) {
|
||||
r = t;
|
||||
};
|
||||
};
|
||||
}));
|
@@ -64,7 +64,7 @@ class Discord extends NotificationProvider {
|
||||
},
|
||||
{
|
||||
name: "Error",
|
||||
value: heartbeatJSON["msg"],
|
||||
value: heartbeatJSON["msg"] == null ? "N/A" : heartbeatJSON["msg"],
|
||||
},
|
||||
],
|
||||
}],
|
||||
|
@@ -8,7 +8,7 @@ console.log("Welcome to Uptime Kuma");
|
||||
// As the log function need to use dayjs, it should be very top
|
||||
const dayjs = require("dayjs");
|
||||
dayjs.extend(require("dayjs/plugin/utc"));
|
||||
dayjs.extend(require("dayjs/plugin/timezone"));
|
||||
dayjs.extend(require("./modules/dayjs/plugin/timezone"));
|
||||
dayjs.extend(require("dayjs/plugin/customParseFormat"));
|
||||
|
||||
// Check Node.js Version
|
||||
|
@@ -1,17 +1,19 @@
|
||||
const { log } = require("../../src/util");
|
||||
const { Settings } = require("../settings");
|
||||
const { sendInfo } = require("../client");
|
||||
const { checkLogin } = require("../util-server");
|
||||
|
||||
module.exports.generalSocketHandler = (socket, server) => {
|
||||
|
||||
socket.on("initServerTimezone", async (timezone) => {
|
||||
try {
|
||||
checkLogin(socket);
|
||||
log.debug("generalSocketHandler", "Timezone: " + timezone);
|
||||
await Settings.set("initServerTimezone", true);
|
||||
await server.setTimezone(timezone);
|
||||
await sendInfo(socket);
|
||||
} catch (e) {
|
||||
|
||||
log.warn("initServerTimezone", e.message);
|
||||
}
|
||||
});
|
||||
|
||||
|
@@ -650,4 +650,23 @@ export default {
|
||||
Enable: "Активирай",
|
||||
Disable: "Деактивирай",
|
||||
dnsCacheDescription: "Възможно е да не работи в IPv6 среда - деактивирайте, ако срещнете проблеми.",
|
||||
"Single Maintenance Window": "Единичен времеви интервал за поддръжка",
|
||||
"Maintenance Time Window of a Day": "Времеви интервал от деня за поддръжка",
|
||||
"Effective Date Range": "Интервал от дни на влизане в сила",
|
||||
"Schedule Maintenance": "Планирай поддръжка",
|
||||
"Date and Time": "Дата и час",
|
||||
"DateTime Range": "Изтрий времеви интервал",
|
||||
Strategy: "Стратегия",
|
||||
"Free Mobile User Identifier": "Free Mobile потребителски идентификатор",
|
||||
"Free Mobile API Key": "Free Mobile API ключ",
|
||||
"Enable TLS": "Активирай TLS",
|
||||
"Proto Service Name": "Proto име на услугата",
|
||||
"Proto Method": "Proto метод",
|
||||
"Proto Content": "Proto съдържание",
|
||||
Economy: "Икономичен",
|
||||
Lowcost: "Евтин",
|
||||
high: "висок",
|
||||
"General Monitor Type": "Общ тип монитор",
|
||||
"Passive Monitor Type": "Пасивет тип монитор",
|
||||
"Specific Monitor Type": "Специфичен тип монитор",
|
||||
};
|
||||
|
@@ -582,4 +582,45 @@ export default {
|
||||
goAlert: "GoAlert",
|
||||
backupOutdatedWarning: "Zastaralé: V poslední době byla funkčnost aplikace značně rozšířena, nicméně součást pro zálohování nepokrývá všechny možnosti. Z tohoto důvodu není možné vygenerovat úplnou zálohu a zajistit obnovení všech dat.",
|
||||
backupRecommend: "Prosím, zálohujte si ručně celý svazek nebo datovou složku (./data/).",
|
||||
"Optional": "Volitelný",
|
||||
squadcast: "Squadcast",
|
||||
SendKey: "SendKey",
|
||||
"SMSManager API Docs": "SMSManager API Docs ",
|
||||
"Gateway Type": "Gateway Typ",
|
||||
SMSManager: "SMSManager",
|
||||
"You can divide numbers with": "Čísla můžete dělit pomocí",
|
||||
"or": "nebo",
|
||||
recurringInterval: "Interval",
|
||||
"Recurring": "Recurring",
|
||||
strategyManual: "Aktivní/Neaktivní Ručně",
|
||||
warningTimezone: "Používá se časové pásmo serveru",
|
||||
weekdayShortMon: "Po",
|
||||
weekdayShortTue: "Út",
|
||||
weekdayShortWed: "St",
|
||||
weekdayShortThu: "Čt",
|
||||
weekdayShortFri: "Pá",
|
||||
weekdayShortSat: "So",
|
||||
weekdayShortSun: "Ne",
|
||||
dayOfWeek: "Den v týdnu",
|
||||
dayOfMonth: "Den v měsíci",
|
||||
lastDay: "Poslední den",
|
||||
lastDay1: "1. poslední den v měsíci",
|
||||
lastDay2: "2. poslední den v měsíci",
|
||||
lastDay3: "3. poslední den v měsíci",
|
||||
lastDay4: "4. poslední den v měsíci",
|
||||
"No Maintenance": "Žádna údržba",
|
||||
pauseMaintenanceMsg: "Jsi si jistý, že chceš pozastavit údržbu?",
|
||||
"maintenanceStatus-under-maintenance": "Údržba",
|
||||
"maintenanceStatus-inactive": "Neaktivní",
|
||||
"maintenanceStatus-scheduled": "Naplánováno",
|
||||
"maintenanceStatus-ended": "Ukončeno",
|
||||
"maintenanceStatus-unknown": "Neznámý",
|
||||
"Display Timezone": "Zobrazit časové pásmo",
|
||||
"Server Timezone": "Časové pásmo serveru",
|
||||
statusPageMaintenanceEndDate: "Konec",
|
||||
IconUrl: "Adresa URL ikony",
|
||||
"Enable DNS Cache": "Povolit DNS Cache",
|
||||
"Enable": "Povolit",
|
||||
"Disable": "Zakázat",
|
||||
dnsCacheDescription: "V některých prostředích IPv6 nemusí fungovat. Pokud narazíte na nějaké problémy, vypněte jej.",
|
||||
};
|
||||
|
@@ -181,7 +181,7 @@ export default {
|
||||
"Degraded Service": "Eingeschränkter Dienst",
|
||||
"Add Group": "Gruppe hinzufügen",
|
||||
"Add a monitor": "Monitor hinzufügen",
|
||||
"Edit Status Page": "Bearbeite Status-Seite",
|
||||
"Edit Status Page": "Statusseite bearbeiten",
|
||||
"Go to Dashboard": "Gehe zum Dashboard",
|
||||
"Status Page": "Status-Seite",
|
||||
"Status Pages": "Status-Seiten",
|
||||
@@ -583,10 +583,10 @@ export default {
|
||||
"Pick Affected Monitors...": "Wähle betroffene Monitore...",
|
||||
"Start of maintenance": "Beginn der Wartung",
|
||||
"All Status Pages": "Alle Status Seiten",
|
||||
"Select status pages...": "Wähle Status Seiten...",
|
||||
recurringIntervalMessage: "einmal pro Tag ausgeführt | Wird alle {0} Tage ausgführt",
|
||||
affectedMonitorsDescription: "Wähle alle Monitore die von der Wartung betroffen sind",
|
||||
affectedStatusPages: "Zeige diese Nachricht auf ausgewählten Status Seiten",
|
||||
"Select status pages...": "Statusseiten auswählen...",
|
||||
recurringIntervalMessage: "Einmal pro Tag ausgeführt | Wird alle {0} Tage ausgführt",
|
||||
affectedMonitorsDescription: "Wähle Monitore aus, die von der aktuellen Wartung betroffen sind",
|
||||
affectedStatusPages: "Diese Wartungsmeldung auf ausgewählten Statusseiten anzeigen",
|
||||
atLeastOneMonitor: "Wähle mindestens einen Monitor",
|
||||
deleteMaintenanceMsg: "Möchtest du diese Wartung löschen?",
|
||||
"Base URL": "Basis URL",
|
||||
@@ -605,8 +605,11 @@ export default {
|
||||
or: "oder",
|
||||
recurringInterval: "Intervall",
|
||||
Recurring: "Wiederkehrend",
|
||||
strategyManual: "Active/Inactive Manually",
|
||||
warningTimezone: "Es wird die Zeitzone des Servers genutzt",
|
||||
"Single Maintenance Window": "Einzigartiges Wartungsfenster",
|
||||
"Maintenance Time Window of a Day": "Zeitfenster für die Wartung",
|
||||
"Effective Date Range": "Bereich der Wirksamkeitsdaten",
|
||||
strategyManual: "Aktiv/Inaktiv Manuell",
|
||||
warningTimezone: "Es wird die Zeitzone des Servers verwendet",
|
||||
weekdayShortMon: "Mo",
|
||||
weekdayShortTue: "Di",
|
||||
weekdayShortWed: "Mi",
|
||||
@@ -622,6 +625,7 @@ export default {
|
||||
lastDay3: "3. letzter Tag im Monat",
|
||||
lastDay4: "4. letzter Tag im Monat",
|
||||
"No Maintenance": "Keine Wartung",
|
||||
"Schedule Maintenance": "Wartung planen",
|
||||
pauseMaintenanceMsg: "Möchtest du wirklich pausieren?",
|
||||
"maintenanceStatus-under-maintenance": "Unter Wartung",
|
||||
"maintenanceStatus-inactive": "Inaktiv",
|
||||
@@ -630,5 +634,8 @@ export default {
|
||||
"maintenanceStatus-unknown": "Unbekannt",
|
||||
"Display Timezone": "Zeitzone anzeigen",
|
||||
"Server Timezone": "Server Zeitzone",
|
||||
"Date and Time": "Datum und Zeit",
|
||||
"DateTime Range": "Datums- und Zeitbereich",
|
||||
Strategy: "Strategie",
|
||||
statusPageMaintenanceEndDate: "Ende",
|
||||
};
|
||||
|
@@ -609,16 +609,16 @@ export default {
|
||||
goAlert: "GoAlert",
|
||||
backupOutdatedWarning: "Deprecated: Since a lot of features added and this backup feature is a bit unmaintained, it cannot generate or restore a complete backup.",
|
||||
backupRecommend: "Please backup the volume or the data folder (./data/) directly instead.",
|
||||
"Optional": "Optional",
|
||||
Optional: "Optional",
|
||||
squadcast: "Squadcast",
|
||||
SendKey: "SendKey",
|
||||
"SMSManager API Docs": "SMSManager API Docs ",
|
||||
"Gateway Type": "Gateway Type",
|
||||
SMSManager: "SMSManager",
|
||||
"You can divide numbers with": "You can divide numbers with",
|
||||
"or": "or",
|
||||
or: "or",
|
||||
recurringInterval: "Interval",
|
||||
"Recurring": "Recurring",
|
||||
Recurring: "Recurring",
|
||||
strategyManual: "Active/Inactive Manually",
|
||||
warningTimezone: "It is using the server's timezone",
|
||||
weekdayShortMon: "Mon",
|
||||
@@ -647,7 +647,26 @@ export default {
|
||||
statusPageMaintenanceEndDate: "End",
|
||||
IconUrl: "Icon URL",
|
||||
"Enable DNS Cache": "Enable DNS Cache",
|
||||
"Enable": "Enable",
|
||||
"Disable": "Disable",
|
||||
Enable: "Enable",
|
||||
Disable: "Disable",
|
||||
dnsCacheDescription: "It may be not working in some IPv6 environments, disable it if you encounter any issues.",
|
||||
"Single Maintenance Window": "Single Maintenance Window",
|
||||
"Maintenance Time Window of a Day": "Maintenance Time Window of a Day",
|
||||
"Effective Date Range": "Effective Date Range",
|
||||
"Schedule Maintenance": "Schedule Maintenance",
|
||||
"Date and Time": "Date and Time",
|
||||
"DateTime Range": "DateTime Range",
|
||||
Strategy: "Strategy",
|
||||
"Free Mobile User Identifier": "Free Mobile User Identifier",
|
||||
"Free Mobile API Key": "Free Mobile API Key",
|
||||
"Enable TLS": "Enable TLS",
|
||||
"Proto Service Name": "Proto Service Name",
|
||||
"Proto Method": "Proto Method",
|
||||
"Proto Content": "Proto Content",
|
||||
Economy: "Economy",
|
||||
Lowcost: "Lowcost",
|
||||
high: "high",
|
||||
"General Monitor Type": "General Monitor Type",
|
||||
"Passive Monitor Type": "Passive Monitor Type",
|
||||
"Specific Monitor Type": "Specific Monitor Type",
|
||||
};
|
||||
|
@@ -186,7 +186,7 @@ export default {
|
||||
startOrEndWithOnly: "Commence uniquement par {0}",
|
||||
"No consecutive dashes": "Pas de double tirets",
|
||||
Next: "Continuer",
|
||||
"Setup Proxy": "Configuer Proxy",
|
||||
"Setup Proxy": "Configurer Proxy",
|
||||
defaultNotificationName: "Ma notification {notification} numéro ({number})",
|
||||
here: "ici",
|
||||
Required: "Requis",
|
||||
|
@@ -5,7 +5,7 @@ export default {
|
||||
retriesDescription: "จำนวนครั้งสูงสุดที่จะลองก่อนบริการถูกระบุว่าไม่สามารถใช้งานได้และส่งการแจ้งเตือน",
|
||||
ignoreTLSError: "ไม่สนใจข้อผิดพลาด TLS/SSL สำหรับเว็บไซต์ HTTPS",
|
||||
upsideDownModeDescription: "กลับด้านสถานะ เช่น ถ้าบริการสามารถใช้งานได้จะถูกเปลี่ยนเป็นใช้งานไม่ได้",
|
||||
maxRedirectDescription: "จำนวนครั้งสูงสุดที่จะเปลี่ยนเส้นทาง, ตั่งเป็น 0 เพื่อปิดการเปลี่ยนเส้นทาง",
|
||||
maxRedirectDescription: "จำนวนครั้งสูงสุดที่จะเปลี่ยนเส้นทาง, ตั้งเป็น 0 เพื่อปิดการเปลี่ยนเส้นทาง",
|
||||
acceptedStatusCodesDescription: "เลือกรหัสสถานะที่ถือว่าการตอบกลับสำเร็จ",
|
||||
passwordNotMatchMsg: "รหัสผ่านไม่ตรงกัน",
|
||||
notificationDescription: "การแจ้งเตือนต้องกำหนดให้มอนิเตอร์เพื่อให้สามารถใช้งานได้",
|
||||
@@ -16,7 +16,7 @@ export default {
|
||||
resolverserverDescription: "Cloudflare เป็นเซิร์ฟเวอร์ค้นหาเริ่มต้น, คุณสามารถเปลี่ยนเซิร์ฟเวอร์ได้ตลอดเวลา",
|
||||
rrtypeDescription: "เลือกประเภท DNS Record ที่คุณต้องการจะมอนิเตอร์",
|
||||
pauseMonitorMsg: "คุณแน่ใจหรือไม่ที่จะหยุดมอนิเตอร์ชั่วคราว?",
|
||||
enableDefaultNotificationDescription: "การแจ้งเตือนนี้จะถูกเปิดโดนค่าเริ่มต้นสำหรับมอนิเตอร์ใหม่, คุณสามารถปิดการแจ้งเตือนสำหรับแต่ละมอนิเตอร์ได้",
|
||||
enableDefaultNotificationDescription: "การแจ้งเตือนนี้จะถูกเปิดโดยค่าเริ่มต้นสำหรับมอนิเตอร์ใหม่, คุณสามารถปิดการแจ้งเตือนสำหรับแต่ละมอนิเตอร์ได้",
|
||||
clearEventsMsg: "คุณแน่ใจหรือไม่ที่จะลบเหตุการณ์ทั้งหมดสำหรับมอนิเตอร์นี้?",
|
||||
clearHeartbeatsMsg: "คุณแน่ใจหรือไม่ที่จะลบประวัติการตรวจสอบทั้งหมดสำหรับมอนิเตอร์นี้?",
|
||||
confirmClearStatisticsMsg: "คุณแน่ใจหรือไม่ที่จะลบสถิติทั้งหมด?",
|
||||
@@ -49,12 +49,12 @@ export default {
|
||||
Status: "สถานะ",
|
||||
DateTime: "วันที่และเวลา",
|
||||
Message: "ข้อความ",
|
||||
"No important events": "ไม่มีกิจกรรมที่สำคัญ",
|
||||
"No important events": "ไม่มีเหตการณ์ที่สำคัญ",
|
||||
Resume: "ดำเนินการต่อ",
|
||||
Edit: "แก้ไข",
|
||||
Delete: "ลบ",
|
||||
Current: "ปัจจุบัน",
|
||||
Uptime: "เวลาที่ใช้งาน",
|
||||
Uptime: "เวลาที่ใช้งานได้",
|
||||
"Cert Exp.": "วันหมดอายุใบรับรอง",
|
||||
days: "วัน",
|
||||
day: "วัน",
|
||||
@@ -69,7 +69,7 @@ export default {
|
||||
URL: "URL",
|
||||
Hostname: "ชื่อโฮสต์",
|
||||
Port: "พอร์ต",
|
||||
"Heartbeat Interval": "ระยะห่างระหว่างการทดสอบ",
|
||||
"Heartbeat Interval": "ระยะเวลาระหว่างการทดสอบ",
|
||||
Retries: "จำนวนครั้งที่จะลองใหม่",
|
||||
"Heartbeat Retry Interval": "ระยะห่างระหว่างการทดสอบใหม่หลังจากไม่สำเร็จ",
|
||||
Advanced: "ขั้นสูง",
|
||||
@@ -112,7 +112,7 @@ export default {
|
||||
No: "ไม่",
|
||||
Username: "ชื่อผู้ใช้",
|
||||
Password: "รหัสผ่าน",
|
||||
"Remember me": "คงอยู่ในระบบ",
|
||||
"Remember me": "จดจำฉันไว้",
|
||||
Login: "เข้าสู่ระบบ",
|
||||
"No Monitors, please": "ไม่มีมอนิเตอร์, กรุณา",
|
||||
"add one": "สร้าง",
|
||||
@@ -120,7 +120,7 @@ export default {
|
||||
Email: "อีเมล",
|
||||
Test: "ทดสอบ",
|
||||
"Certificate Info": "ข้อมูลใบรับรอง",
|
||||
"Resolver Server": "เซิร์ฟเวอร์ทีค้นหา",
|
||||
"Resolver Server": "เซิร์ฟเวอร์ที่ค้นหา",
|
||||
"Resource Record Type": "ประเภท DNS Record",
|
||||
"Last Result": "ผลล่าสุด",
|
||||
"Create your admin account": "สร้างบัญชีผู้ดูแลระบบ",
|
||||
@@ -138,8 +138,8 @@ export default {
|
||||
Events: "เหตุการณ์",
|
||||
Heartbeats: "ประวัติการตรวจสอบ",
|
||||
"Auto Get": "ดึงอัตโนมัติ",
|
||||
backupDescription: "คุณสามารถสำรองข้อมูลการแจ้งเตือนและมอนิเตอร์ทั้งหมดได้ในไฟล์ JSON",
|
||||
backupDescription2: "หมายเหตุ : ประวัติและข้อมูลกิจกรรมจะไม่ถูกสำรอง",
|
||||
backupDescription: "คุณสามารถสำรองข้อมูลการแจ้งเตือนและมอนิเตอร์ทั้งหมดไว้ได้ในไฟล์ JSON",
|
||||
backupDescription2: "หมายเหตุ : ประวัติและข้อมูลเหตการณ์จะไม่ถูกสำรอง",
|
||||
backupDescription3: "ข้อมูลที่ละเอียดอ่อนเช่นกุญแจการแจ้งเตือนจะรวมอยู่ในไฟล์ข้อมูลสำรอง, โปรดเก็บข้อมูลสำรองอย่างปลอดภัย",
|
||||
alertNoFile: "กรุณาเลือกไฟล์ที่จะใช้งาน",
|
||||
alertWrongFileType: "กรุณาเลือกไฟล์ที่เป็น JSON",
|
||||
@@ -153,7 +153,7 @@ export default {
|
||||
"Enable 2FA": "เปิดใช้งาน 2FA",
|
||||
"Disable 2FA": "ปิดใช้งาน 2FA",
|
||||
"2FA Settings": "ตั้งค่า 2FA",
|
||||
"Two Factor Authentication": "การตรวจสอบสิทธิ์สองปัจจัย",
|
||||
"Two Factor Authentication": "การยืนยันตัวตนแบบสองขั้นตอน",
|
||||
Active: "ใช้งาน",
|
||||
Inactive: "ไม่ใช้งาน",
|
||||
Token: "กุญแจ",
|
||||
@@ -189,7 +189,7 @@ export default {
|
||||
"Status Pages": "หน้าสถานะ",
|
||||
defaultNotificationName: "การแจ้งเตือน {notification} ของฉัน ({number})",
|
||||
here: "ที่นี่",
|
||||
Required: "ต้องการ",
|
||||
Required: "จำเป็น",
|
||||
telegram: "Telegram",
|
||||
"Bot Token": "กุญแจของบอท",
|
||||
wayToGetTelegramToken: "คุณสามารถรับกุญแจได้จาก {0}.",
|
||||
@@ -202,7 +202,7 @@ export default {
|
||||
"Post URL": "URL โพสต์",
|
||||
"Content Type": "ประเภทเนื้อหา",
|
||||
webhookJsonDesc: "{0} ดีสำหรับเซิร์ฟเวอร์ HTTP สมัยใหม่เช่น Express.js",
|
||||
webhookFormDataDesc: "{multipart} ดีสำหรับ PHP, JSON จะต้องถูกประมวลผลด้วย {decodeFunction}",
|
||||
webhookFormDataDesc: "{multipart} ดีสำหรับ PHP, ข้อมูล JSON จะต้องถูกประมวลผลด้วย {decodeFunction}",
|
||||
smtp: "Email (SMTP)",
|
||||
secureOptionNone: "None / STARTTLS (25, 587)",
|
||||
secureOptionTLS: "TLS (465)",
|
||||
@@ -224,7 +224,7 @@ export default {
|
||||
signal: "Signal",
|
||||
Number: "หมายเลข",
|
||||
Recipients: "ผู้รับ",
|
||||
needSignalAPI: "คุณต้องมี Signal Client ที่มี Rest APIl",
|
||||
needSignalAPI: "คุณต้องมี Signal Client ที่มี Rest API",
|
||||
wayToCheckSignalURL: "คุณสามารถตรวจสอบ URL นี้เพื่อดูวิธีตั้งค่า :",
|
||||
signalImportant: "สำคัญ: คุณไม่สามารถผสมกลุ่มและตัวเลขในผู้รับได้!",
|
||||
gotify: "Gotify",
|
||||
@@ -236,7 +236,7 @@ export default {
|
||||
"Channel Name": "ชื่อห้อง",
|
||||
"Uptime Kuma URL": "Uptime Kuma URL",
|
||||
aboutWebhooks: "ข้อมูลเพิ่มเติมสำหรับ Webhooks : {0}",
|
||||
aboutChannelName: "ใส่ชื่อห้องบน {0} ในช่องชื่อห้องถ้าต้องการที่จะข้าม Webhook, เช่น: #ช่องอื่นๆ",
|
||||
aboutChannelName: "ใส่ชื่อห้องใน {0} ในช่องชื่อห้องถ้าต้องการที่จะข้าม Webhook, เช่น: #ช่องอื่นๆ",
|
||||
aboutKumaURL: "ถ้าคุณไม่ใส่ข้อมูลในช่อง Uptime Kuma URL ค่าเริ่มต้นจะเป็นจะเป็น Uptime Kuma Github",
|
||||
emojiCheatSheet: "ตาราง Emoji : {0}",
|
||||
"rocket.chat": "Rocket.Chat",
|
||||
@@ -248,7 +248,7 @@ export default {
|
||||
clicksendsms: "ClickSend SMS",
|
||||
lunasea: "LunaSea",
|
||||
apprise: "Apprise (รองรับการแจ้งเตือนมากกว่า 50 บริการ)",
|
||||
GoogleChat: "Google Chat (Google Workspace only)",
|
||||
GoogleChat: "Google Chat (สำหรับ Google Workspace เท่านั้น)",
|
||||
pushbullet: "Pushbullet",
|
||||
line: "Line Messenger",
|
||||
mattermost: "Mattermost",
|
||||
@@ -257,8 +257,8 @@ export default {
|
||||
"Message Title": "หัวข้อข้อความ",
|
||||
"Notification Sound": "เสียงแจ้งเตือน",
|
||||
"More info on:": "ข้อมูลเพิ่มเติม : {0}",
|
||||
pushoverDesc1: "ลำดับความสำตคญฉุกเฉิน (2) มีการหมดเวลาเริ่มต้น 30 วินาทีระหว่างลองใหม่และจะหมดอายุหลังจาก 1 ชั่วโมง",
|
||||
pushoverDesc2: "ถ้าคุณต้องการจะส่งการแจ้งเตือนไปยังอุปกรณ์อื่น ๆ สามารถกำหนดได้ที่ช่องอุปกรณ์",
|
||||
pushoverDesc1: "ลำดับความสำคัญฉุกเฉิน (2) มีการหมดเวลาเริ่มต้น 30 วินาทีระหว่างการลองใหม่และจะหมดอายุหลังจาก 1 ชั่วโมง",
|
||||
pushoverDesc2: "ถ้าคุณต้องการจะส่งการแจ้งเตือนไปยังอุปกรณ์อื่นๆ สามารถกำหนดได้ที่ช่องอุปกรณ์",
|
||||
"SMS Type": "ประเภท SMS",
|
||||
octopushTypePremium: "พรีเมี่ยม (เร็ว - แนะนำสำหรับการแจ้งเตือน)",
|
||||
octopushTypeLowCost: "ต้นทุนต่ำ (ช้า - บางครั้งจะถูกบล็อกโดยผู้ให้บริการ)",
|
||||
@@ -274,8 +274,8 @@ export default {
|
||||
"Read more:": "อ่านเพิ่มเติม : {0}",
|
||||
"Status:": "สถานะ : {0}",
|
||||
"Read more": "อ่านเพิ่มเติม",
|
||||
appriseInstalled: "Apprise ถูกติดตั่งแล้ว",
|
||||
appriseNotInstalled: "Apprise ยังไม่ถูกติดตั่ง {0}",
|
||||
appriseInstalled: "Apprise ถูกติดตั้งแล้ว",
|
||||
appriseNotInstalled: "Apprise ยังไม่ถูกติดตั้ง {0}",
|
||||
"Access Token": "กุญแจการเข้าถึง",
|
||||
"Channel access token": "กุญแจการเข้าถึงของช่อง",
|
||||
"Line Developers Console": "Line Developers Console",
|
||||
@@ -285,11 +285,11 @@ export default {
|
||||
"Messaging API": "Messaging API",
|
||||
wayToGetLineChannelToken: "ขั้นแรกให้เข้า {0} สร้างผู้ให้บริการและช่องทาง (Messaging API) จากนั้นคุณจะได้รับกุญแจการเข้าถึงช่องและไอดีผู้ใช้จากรายการเมนูที่กล่าวถึงข้างต้น",
|
||||
"Icon URL": "Icon URL",
|
||||
aboutIconURL: "คุณสามารถระบุลิงก์ไปยังรูปภาพใน \"URL ไอคอน\" เพื่อแทนที่รูปภาพโปรไฟล์เริ่มต้น จะไม่ถูกใช้หากมีการตั้งค่า Icon Emoji",
|
||||
aboutMattermostChannelName: "คุณลบล้างช่องเริ่มต้นที่ Webhook โพสต์ได้ด้วยการป้อนชื่อช่องลงในช่อง \"ชื่อช่อง\" ต้องเปิดใช้งานในการตั้งค่า Mattermost Webhook เช่น #ช่องอื่นๆ",
|
||||
aboutIconURL: "คุณสามารถระบุลิงก์รูปภาพใน \"URL ไอคอน\" เพื่อแทนที่รูปภาพโปรไฟล์เริ่มต้น จะไม่ถูกใช้หากมีการตั้งค่า Icon Emoji",
|
||||
aboutMattermostChannelName: "คุณลบช่องเริ่มต้นที่ Webhook โพสต์ได้ด้วยการป้อนชื่อช่องลงในช่อง \"ชื่อช่อง\" ต้องเปิดใช้งานในการตั้งค่า Mattermost Webhook เช่น #ช่องอื่นๆ",
|
||||
matrix: "Matrix",
|
||||
promosmsTypeEco: "SMS ECO - ราคาถูก แต่ช้าและมักจะโอเวอร์โหลด จำกัดเฉพาะผู้รับโปแลนด์",
|
||||
promosmsTypeFlash: "SMS FLASH - ข้อความจะแสดงบนอุปกรณ์ของผู้รับโดยอัตโนมัติ จำกัดเฉพาะผู้รับโปแลนด์",
|
||||
promosmsTypeEco: "SMS ECO - ราคาถูก แต่ช้าและมักจะโอเวอร์โหลด จำกัดเฉพาะผู้รับในโปแลนด์",
|
||||
promosmsTypeFlash: "SMS FLASH - ข้อความจะแสดงบนอุปกรณ์ของผู้รับโดยอัตโนมัติ จำกัดเฉพาะผู้รับในโปแลนด์",
|
||||
promosmsTypeFull: "SMS FULL - SMS ระดับพรีเมียม คุณสามารถใช้ชื่อผู้ส่งของคุณได้ (คุณต้องลงทะเบียนชื่อก่อน) เชื่อถือได้สำหรับการแจ้งเตือน",
|
||||
promosmsTypeSpeed: "SMS SPEED - ลำดับความสำคัญสูงสุดในระบบ รวดเร็วและเชื่อถือได้ แต่มีค่าใช้จ่ายสูง (ประมาณสองเท่าของราคาเต็ม SMS)",
|
||||
promosmsPhoneNumber: "หมายเลขโทรศัพท์ (สำหรับผู้รับโปแลนด์ คุณสามารถข้ามรหัสพื้นที่ได้)",
|
||||
@@ -298,7 +298,7 @@ export default {
|
||||
matrixHomeserverURL: "URL ของโฮมเซิร์ฟเวอร์ (พร้อม http(s):// และพอร์ตเสริม)",
|
||||
"Internal Room Id": "รหัสห้องภายใน",
|
||||
matrixDesc1: "คุณค้นหารหัสห้องภายในได้โดยดูในส่วนขั้นสูงของการตั้งค่าห้องในไคลเอ็นต์ Matrix มันควรจะมีลักษณะเช่น !PMdRCpsIfLwsfjIye6:kiznick.server.",
|
||||
matrixDesc2: "ขอแนะนำเป็นอย่างยิ่งให้คุณสร้างผู้ใช้ใหม่และอย่าใช้โทเค็นการเข้าถึงของผู้ใช้ Matrix ของคุณเอง เนื่องจากจะทำให้สามารถเข้าถึงบัญชีของคุณและห้องทั้งหมดที่คุณเข้าร่วมได้อย่างเต็มที่ ให้สร้างผู้ใช้ใหม่และเชิญเฉพาะห้องที่คุณต้องการรับการแจ้งเตือนแทน คุณสามารถรับโทเค็นเพื่อการเข้าถึงได้โดยเรียกใช้ {0}",
|
||||
matrixDesc2: "ขอแนะนำเป็นอย่างยิ่งให้คุณสร้างผู้ใช้ใหม่และอย่าใช้โทเค็นการเข้าถึงของผู้ใช้ Matrix ของคุณเอง เนื่องจากจะทำให้สามารถเข้าถึงบัญชีของคุณและห้องทั้งหมดที่คุณเข้าร่วม ให้สร้างผู้ใช้ใหม่และเชิญเฉพาะห้องที่คุณต้องการรับการแจ้งเตือนแทน คุณสามารถรับโทเค็นเพื่อการเข้าถึงได้โดยเรียกใช้ {0}",
|
||||
Method: "วิธี",
|
||||
Body: "เนื้อหา",
|
||||
Headers: "ส่วนหัว",
|
||||
@@ -310,12 +310,12 @@ export default {
|
||||
PasswordsDoNotMatch: "รหัสผ่านไม่ตรงกัน",
|
||||
records: "บันทึก",
|
||||
"One record": "หนึ่งบันทึก",
|
||||
steamApiKeyDescription: "สำหรับการมอนิเตอร์ Steam Game Server คุณต้องมี Steam Web-API key, คุณสามารถรสมัครได้จากที่นี่ : ",
|
||||
steamApiKeyDescription: "สำหรับการมอนิเตอร์ Steam Game Server คุณต้องมี Steam Web-API key, คุณสามารถสมัครได้จากที่นี่ : ",
|
||||
"Current User": "ผู้ใช้ปัจจุบัน",
|
||||
topic: "หัวข้อ",
|
||||
topicExplanation: "MQTT หัวข้อที่จะมอนิเตอร์",
|
||||
topicExplanation: "หัวข้อ MQTT ที่จะมอนิเตอร์",
|
||||
successMessage: "ข้อความที่จะถือว่าประสบความสำเร็จ",
|
||||
successMessageExplanation: "MQTT ข้อความที่จะถือว่าประสบความสำเร็จ",
|
||||
successMessageExplanation: "ข้อความ MQTT ที่จะถือว่าประสบความสำเร็จ",
|
||||
recent: "ล่าสุด",
|
||||
Done: "สำเร็จ",
|
||||
Info: "ข้อมูล",
|
||||
@@ -354,7 +354,7 @@ export default {
|
||||
Discard: "ทิ้ง",
|
||||
Cancel: "ยกเลิก",
|
||||
"Powered by": "ขับเคลื่อนโดย",
|
||||
shrinkDatabaseDescription: "ทริกเกอร์ฐานข้อมูล VACUUM สำหรับ SQLite หากฐานข้อมูลของคุณถูกสร้างขึ้นหลังจาก 1.10.0 แสดงว่า AUTO_VACUUM เปิดใช้งานอยู่แล้วและไม่จำเป็นต้องดำเนินการนี้",
|
||||
shrinkDatabaseDescription: "ทริกเกอร์ฐานข้อมูล VACUUM สำหรับ SQLite หากฐานข้อมูลของคุณถูกสร้างขึ้นหลังจากเวอร์ชั่น 1.10.0 แสดงว่า AUTO_VACUUM เปิดใช้งานอยู่แล้วและไม่จำเป็นต้องดำเนินการนี้",
|
||||
serwersms: "SerwerSMS.pl",
|
||||
serwersmsAPIUser: "API Username (incl. webapi_ prefix)",
|
||||
serwersmsAPIPassword: "API Password",
|
||||
@@ -364,14 +364,14 @@ export default {
|
||||
Customize: "ปรับแต่ง",
|
||||
"Custom Footer": "ส่วนท้ายที่กำหนดเอง",
|
||||
"Custom CSS": "CSS ที่กำหนดเอง",
|
||||
smtpDkimSettings: "ตั้งค่า DKIM",
|
||||
smtpDkimSettings: "การตั้งค่า DKIM",
|
||||
smtpDkimDesc: "โปรดดู Nodemailer DKIM {0} สำหรับการใช้งาน",
|
||||
documentation: "เอกสาร",
|
||||
documentation: "คู่มือการใช้งาน",
|
||||
smtpDkimDomain: "ชื่อโดเมน",
|
||||
smtpDkimKeySelector: "Key Selector",
|
||||
smtpDkimPrivateKey: "Private Key",
|
||||
smtpDkimHashAlgo: "อัลกอริทึมแฮช (ไม่บังคับ)",
|
||||
smtpDkimheaderFieldNames: "คีย์ส่วนหัวเพื่อลงชื่อ (ไม่บังคับ)",
|
||||
smtpDkimheaderFieldNames: "คีย์ส่วนหัวสำหรับลงชื่อ (ไม่บังคับ)",
|
||||
smtpDkimskipFields: "Header Keys ไม่ต้องเซ็น (ไม่บังคับ)",
|
||||
gorush: "Gorush",
|
||||
alerta: "Alerta",
|
||||
@@ -383,11 +383,11 @@ export default {
|
||||
deleteStatusPageMsg: "คุณแน่ใจหรือไม่ว่าต้องการลบหน้าสถานะนี้",
|
||||
Proxies: "พร็อกซี",
|
||||
default: "ค่าเริ่มต้น",
|
||||
enabled: "เปิดใช้งาน",
|
||||
setAsDefault: "ตั่งเป็นค่าเริ่มต้น",
|
||||
enabled: "เปิดใช้งานแล้ว",
|
||||
setAsDefault: "ตั้งเป็นค่าเริ่มต้น",
|
||||
deleteProxyMsg: "คุณแน่ใจหรือไม่ว่าต้องการลบพร็อกซีสำหรับมอนิเตอร์ทั้งหมด?",
|
||||
proxyDescription: "พร็อกซีจะต้องตั้งค่าให้มอนิเตอร์เพื่อให้ใช้งานได้",
|
||||
enableProxyDescription: "พร็อกซีนี้จะไม่ส่งผลต่อมอนิเตอร์จนกว่าจะเปิดใช้งาน คุณสามารถควบคุมการปิดใช้งานพร็อกซีชั่วคราวจากมอนิเตอร์ทั้งหมดได้โดยสถานะการเปิดใช้งาน",
|
||||
proxyDescription: "ต้องตั้งค่ามอนิเตอร์ให้ใช้พร็อกซีเพื่อให้ใช้งานได้",
|
||||
enableProxyDescription: "พร็อกซีนี้จะไม่ส่งผลต่อมอนิเตอร์จนกว่าจะเปิดใช้งาน คุณสามารถควบคุมการปิดใช้งานพร็อกซีชั่วคราวจากมอนิเตอร์ทั้งหมดได้ที่ส่วนสถานะการเปิดใช้งาน",
|
||||
setAsDefaultProxyDescription: "พร็อกซีนี้จะถูกเปิดโดนค่าเริ่มต้นสำหรับมอนิเตอร์ใหม่, คุณสามารถปิดการแจ้งเตือนสำหรับแต่ละมอนิเตอร์ได้",
|
||||
"Certificate Chain": "ห่วงโซ่ใบรับรอง",
|
||||
Valid: "ถูกต้อง",
|
||||
@@ -413,7 +413,7 @@ export default {
|
||||
"WeCom Bot Key": "WeCom Bot Key",
|
||||
"Setup Proxy": "ติดตั้งพร็อกซี่",
|
||||
"Proxy Protocol": "โปรโตคอลพร็อกซี่",
|
||||
"Proxy Server": "พร็อกซีเซิร์ฟ",
|
||||
"Proxy Server": "เซิร์ฟเวอร์พร็อกซี",
|
||||
"Proxy server has authentication": "พร็อกซีเซิร์ฟเวอร์มีการตรวจสอบสิทธิ์",
|
||||
User: "ผู้ใช้",
|
||||
Installed: "ติดตั้งแล้ว",
|
||||
@@ -430,29 +430,29 @@ export default {
|
||||
startOrEndWithOnly: "เริ่มหรือจบด้วย {0} เท่านั้น",
|
||||
"No consecutive dashes": "ไม่มีขีดกลางติดต่อกัน",
|
||||
Next: "ต่อไป",
|
||||
"The slug is already taken. Please choose another slug.": "ชื่อนี้ถูกใช้งานไปแล้ว กรุณาใช้ชื่ออื่น",
|
||||
"The slug is already taken. Please choose another slug.": "ชื่อนี้ถูกใช้งานแล้ว กรุณาใช้ชื่ออื่น",
|
||||
"No Proxy": "ไม่มีพร็อกซี่",
|
||||
"HTTP Basic Auth": "HTTP Basic Auth",
|
||||
"New Status Page": "หน้าสถานะใหม่",
|
||||
"Page Not Found": "ไม่พบหน้านี้",
|
||||
"Reverse Proxy": "พร็อกซีย้อนกลับ",
|
||||
Backup: "สำรอง",
|
||||
Backup: "สำรองข้อมูล",
|
||||
About: "เกี่ยวกับ",
|
||||
wayToGetCloudflaredURL: "(ดาวโหลด cloudflared จาก {0})",
|
||||
cloudflareWebsite: "เว็บไซต์ Cloudflare",
|
||||
"Message:": "ข้อความ :",
|
||||
"Don't know how to get the token? Please read the guide:": "ไม่รู้วิธีการรับกุญแจ?, กรุณาอ่านคู่มือ",
|
||||
"The current connection may be lost if you are currently connecting via Cloudflare Tunnel. Are you sure want to stop it? Type your current password to confirm it.": "การเชื่อมต่อปัจุบันอาจขาดหายหากคุณกำลังเชื่อมต่อ Cloudflare Tunnel คุณแน่ใจหรือไม่ที่จะหยุด, พิมรหัสผ่านของคุณเพื่อยืนยัน",
|
||||
"Other Software": "ซอฟต์แวร์อื่น ๆ ",
|
||||
"Other Software": "ซอฟต์แวร์อื่นๆ ",
|
||||
"For example: nginx, Apache and Traefik.": "เช่น: nginx, Apache และ Traefik",
|
||||
"Please read": "กรุณาอ่าน",
|
||||
"Subject:": "เรื่อง :",
|
||||
"Valid To:": "ถูกต้องถึง :",
|
||||
"Valid To:": "ใช้ได้ถึง :",
|
||||
"Days Remaining:": "จำนวนวันที่เหลือ :",
|
||||
"Issuer:": "ผู้ออก :",
|
||||
"Fingerprint:": "ลายนิ้วมือ :",
|
||||
"No status pages": "ไม่มีหน้าสถานะ",
|
||||
"Domain Name Expiry Notification": "แจ้งเตือนการหมดอายุโดเมน",
|
||||
"Domain Name Expiry Notification": "แจ้งเตือนการหมดอายุของโดเมน",
|
||||
Proxy: "Proxy",
|
||||
"Date Created": "วันที่สร้าง",
|
||||
onebotHttpAddress: "ที่อยู่ HTTP OneBot ",
|
||||
@@ -466,8 +466,8 @@ export default {
|
||||
"Show Powered By": "แสดงข้อความ \"ขับเคลื่อนโดย\"",
|
||||
"Domain Names": "Domain Names",
|
||||
signedInDisp: "เข้าใช้งานในฐานะ {0}",
|
||||
signedInDispDisabled: "ปิดการตรวจสอบสิทธิ์",
|
||||
"Certificate Expiry Notification": "แจ้งเตือนการรับรองหมดอายุ",
|
||||
signedInDispDisabled: "ปิดการยืนยันตัวตน",
|
||||
"Certificate Expiry Notification": "แจ้งเตือนใบรับรองหมดอายุ",
|
||||
"API Username": "API Username",
|
||||
"API Key": "API Key",
|
||||
"Recipient Number": "หมายเลขผู้รับ",
|
||||
@@ -476,8 +476,8 @@ export default {
|
||||
"Octopush API Version": "Octopush API Version",
|
||||
"Legacy Octopush-DM": "Legacy Octopush-DM",
|
||||
endpoint: "endpoint",
|
||||
octopushAPIKey: "\"API key\" จากข้อมูลรับรอง HTTP API ในแผงควบคุม",
|
||||
octopushLogin: "\"Login\" จากข้อมูลรับรอง HTTP API ในแผงควบคุม",
|
||||
octopushAPIKey: "\"API key\" จากข้อมูลยืนยันตัวตน HTTP API ในแผงควบคุม",
|
||||
octopushLogin: "\"Login\" จากข้อมูลยืนยันตัวตน HTTP API ในแผงควบคุม",
|
||||
promosmsLogin: "API Login Name",
|
||||
promosmsPassword: "API Password",
|
||||
"pushoversounds pushover": "Pushover (default)",
|
||||
@@ -507,16 +507,16 @@ export default {
|
||||
pushyToken: "Device token",
|
||||
"Show update if available": "แสดงการอัปเดตถ้ามี",
|
||||
"Also check beta release": "ตรวจสอบรุ่นเบต้า",
|
||||
"Using a Reverse Proxy?": "ใช้ Reverse Proxy?",
|
||||
"Using a Reverse Proxy?": "ใช้ Reverse Proxy อยู่ใช่มั้ย?",
|
||||
"Check how to config it for WebSocket": "ตรวจสอบวิธีการตั้งค่าสำหรับ WebSocket",
|
||||
"Steam Game Server": "Steam Game Server",
|
||||
"Most likely causes:": "สาเหตุที่เป็นไปได้มากที่สุด :",
|
||||
"The resource is no longer available.": "ทรัพยากรไม่สามารถใช้งานได้อีกต่อไป",
|
||||
"There might be a typing error in the address.": "อาจมีข้อผิดพลาดในการพิมพ์ที่อยู่",
|
||||
"What you can try:": "สิ่งที่คุณสามารถลอง :",
|
||||
"What you can try:": "สิ่งที่คุณสามารถลองทำ :",
|
||||
"Retype the address.": "พิมพ์ที่อยู่อีกครั้ง",
|
||||
"Go back to the previous page.": "กลับไปที่หน้าก่อนหน้า",
|
||||
"Coming Soon": "เร็ว ๆ นี้",
|
||||
"Go back to the previous page.": "กลับไปหน้าที่แล้ว",
|
||||
"Coming Soon": "เร็วๆ นี้",
|
||||
wayToGetClickSendSMSToken: "คุณสามารถรับ API Username และ API Key ได้จาก {0}",
|
||||
wayToGetLineNotifyToken: "คุณสามารถรับ access token ได้จาก {0}",
|
||||
resendEveryXTimes: "ส่งซ้ำทุก {0} ครั้ง",
|
||||
@@ -525,7 +525,7 @@ export default {
|
||||
"Resend Notification if Down X times consequently": "ส่งการแจ้งเตือนซ้ำถ้าออฟไลน์ครบ X ครั้ง",
|
||||
error: "เกิดข้อผิดพลาด",
|
||||
critical: "วิกฤต",
|
||||
wayToGetPagerDutyKey: "คุณสามารถรับได้โดยการไปที่ Service -> Service Directory -> (Select a service) -> Integrations -> Add integration, และค้นหา \"Events API V2\", สำหรับข้อมูลเพิ่มเติม {0}",
|
||||
wayToGetPagerDutyKey: "คุณสามารถรับคีย์ได้โดยการไปที่ Service -> Service Directory -> (Select a service) -> Integrations -> Add integration, และค้นหา \"Events API V2\", สำหรับข้อมูลเพิ่มเติม {0}",
|
||||
"Integration Key": "Integration Key",
|
||||
"Integration URL": "Integration URL",
|
||||
"Auto resolve or acknowledged": "แก้ไขอัตโนมัติหรือยอมรับ",
|
||||
@@ -539,16 +539,16 @@ export default {
|
||||
"Trust Proxy": "Trust Proxy",
|
||||
HomeAssistant: "Home Assistant",
|
||||
RadiusSecret: "Radius Secret",
|
||||
RadiusSecretDescription: "แบ่งปันข้อมูลลับระหว่างผู้ใช้งานและเซิร์ฟเวอร์",
|
||||
RadiusSecretDescription: "แบ่งปันคีย์ลับระหว่างผู้ใช้งานและเซิร์ฟเวอร์",
|
||||
RadiusCalledStationId: "Called Station Id",
|
||||
RadiusCalledStationIdDescription: "Identifier of the called device",
|
||||
RadiusCallingStationId: "Calling Station Id",
|
||||
RadiusCallingStationIdDescription: "Identifier of the calling device",
|
||||
"Connection String": "Connection String",
|
||||
Query: "Query",
|
||||
settingsCertificateExpiry: "วันหมดอายุใบรับรอง TLS",
|
||||
certificationExpiryDescription: "การตรวจสอบ HTTPS แจ้งเตือนใบอนุญาติ TLS จะหมดอายุใน:",
|
||||
"Setup Docker Host": "Setup Docker Host",
|
||||
settingsCertificateExpiry: "วันหมดอายุของใบรับรอง TLS",
|
||||
certificationExpiryDescription: "การตรวจสอบ HTTPS จะแจ้งเตือนถ้าใบอนุญาติ TLS จะหมดอายุใน:",
|
||||
"Setup Docker Host": "ติดตั้ง Docker Host",
|
||||
"Connection Type": "ประเภทการเชื่อมต่อ",
|
||||
"Docker Daemon": "Docker Daemon",
|
||||
deleteDockerHostMsg: "คุณแน่ใจหรือไม่ที่จะลบ Docker host นี้สำหรับการมอนิเตอร์ทั้งหมด?",
|
||||
@@ -565,14 +565,14 @@ export default {
|
||||
trustProxyDescription: "เชื่อ Header 'X-Forwarded-*' ถ้าคุณต้องการไอพีที่ถูกต้องและ Uptime Kuma อยู่ข้างหลัง Nginx หรือ Apache, คุณควรเปิดใช้งาน",
|
||||
Examples: "ตัวอย่าง",
|
||||
"Home Assistant URL": "Home Assistant URL",
|
||||
"Long-Lived Access Token": "Access Token แบบมีอายุ",
|
||||
"Long-Lived Access Token": "Access Token แบบมีอายุนาน",
|
||||
"Long-Lived Access Token can be created by clicking on your profile name (bottom left) and scrolling to the bottom then click Create Token. ": "Access Token แบบมีอายุนานสามารถสร้างได้โดยคลิกชื่อบนโปรไฟล์ (ล่างซ้าย) และเลื่อนไปข้างล่างจากนั้นคลิก \"Create Token\"",
|
||||
"Notification Service": "บริการแจ้งเตือน",
|
||||
"default: notify all devices": "ค่าเริ่มต้น: แจ้งเตือนทุกอุปกรณ์",
|
||||
"A list of Notification Services can be found in Home Assistant under \"Developer Tools > Services\" search for \"notification\" to find your device/phone name.": "รายการแจ้งเตือนสามารถหาได้ใน Home Assistant ในเมนู \"Developer Tools > Services\" ค้นหา \"notification\" เพื่อหาชื่ออุปกรณ์หรือชื่อโทรศัพท์",
|
||||
"A list of Notification Services can be found in Home Assistant under \"Developer Tools > Services\" search for \"notification\" to find your device/phone name.": "รายการแจ้งเตือนสามารถหาได้ใน Home Assistant ในเมนู \"Developer Tools > Services\" แล้วค้นหา \"notification\" เพื่อหาชื่ออุปกรณ์หรือชื่อโทรศัพท์",
|
||||
"Automations can optionally be triggered in Home Assistant:": "สามารถเลือกสั่งงานระบบอัตโนมัติได้ใน Home Assistant:",
|
||||
"Trigger type:": "ชนิดสิ่งกระตุ้น:",
|
||||
"Event type:": "ชนิดกิจกรรม:",
|
||||
"Event type:": "ชนิดเหตการณ์:",
|
||||
"Event data:": "ข้อมูลกิจกรรม:",
|
||||
"Then choose an action, for example switch the scene to where an RGB light is red.": "จากนั้นเลือกการกระทำ, ตัวอย่าง เช่น เปลี่ยนเป็นไฟสีแดง",
|
||||
"Frontend Version": "เวอร์ชั่น Frontend",
|
||||
|
@@ -17,7 +17,7 @@ import lang from "./mixins/lang";
|
||||
import { router } from "./router";
|
||||
import { appName } from "./util.ts";
|
||||
import dayjs from "dayjs";
|
||||
import timezone from "dayjs/plugin/timezone";
|
||||
import timezone from "./modules/dayjs/plugin/timezone";
|
||||
import utc from "dayjs/plugin/utc";
|
||||
import relativeTime from "dayjs/plugin/relativeTime";
|
||||
dayjs.extend(utc);
|
||||
|
@@ -590,7 +590,7 @@ export default {
|
||||
for (let monitorID in this.lastHeartbeatList) {
|
||||
let lastHeartBeat = this.lastHeartbeatList[monitorID];
|
||||
|
||||
if (this.monitorList[monitorID].maintenance) {
|
||||
if (this.monitorList[monitorID] && this.monitorList[monitorID].maintenance) {
|
||||
result[monitorID] = {
|
||||
text: this.$t("statusMaintenance"),
|
||||
color: "maintenance",
|
||||
|
25
src/modules/dayjs/constant.js
Normal file
25
src/modules/dayjs/constant.js
Normal file
@@ -0,0 +1,25 @@
|
||||
export let SECONDS_A_MINUTE = 60;
|
||||
export let SECONDS_A_HOUR = SECONDS_A_MINUTE * 60;
|
||||
export let SECONDS_A_DAY = SECONDS_A_HOUR * 24;
|
||||
export let SECONDS_A_WEEK = SECONDS_A_DAY * 7;
|
||||
export let MILLISECONDS_A_SECOND = 1e3;
|
||||
export let MILLISECONDS_A_MINUTE = SECONDS_A_MINUTE * MILLISECONDS_A_SECOND;
|
||||
export let MILLISECONDS_A_HOUR = SECONDS_A_HOUR * MILLISECONDS_A_SECOND;
|
||||
export let MILLISECONDS_A_DAY = SECONDS_A_DAY * MILLISECONDS_A_SECOND;
|
||||
export let MILLISECONDS_A_WEEK = SECONDS_A_WEEK * MILLISECONDS_A_SECOND; // English locales
|
||||
|
||||
export let MS = "millisecond";
|
||||
export let S = "second";
|
||||
export let MIN = "minute";
|
||||
export let H = "hour";
|
||||
export let D = "day";
|
||||
export let W = "week";
|
||||
export let M = "month";
|
||||
export let Q = "quarter";
|
||||
export let Y = "year";
|
||||
export let DATE = "date";
|
||||
export let FORMAT_DEFAULT = "YYYY-MM-DDTHH:mm:ssZ";
|
||||
export let INVALID_DATE_STRING = "Invalid Date"; // regex
|
||||
|
||||
export let REGEX_PARSE = /^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/;
|
||||
export let REGEX_FORMAT = /\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g;
|
20
src/modules/dayjs/plugin/timezone/index.d.ts
vendored
Normal file
20
src/modules/dayjs/plugin/timezone/index.d.ts
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
import { PluginFunc, ConfigType } from 'dayjs/esm'
|
||||
|
||||
declare const plugin: PluginFunc
|
||||
export = plugin
|
||||
|
||||
declare module 'dayjs/esm' {
|
||||
interface Dayjs {
|
||||
tz(timezone?: string, keepLocalTime?: boolean): Dayjs
|
||||
offsetName(type?: 'short' | 'long'): string | undefined
|
||||
}
|
||||
|
||||
interface DayjsTimezone {
|
||||
(date: ConfigType, timezone?: string): Dayjs
|
||||
(date: ConfigType, format: string, timezone?: string): Dayjs
|
||||
guess(): string
|
||||
setDefault(timezone?: string): void
|
||||
}
|
||||
|
||||
const tz: DayjsTimezone
|
||||
}
|
188
src/modules/dayjs/plugin/timezone/index.js
Normal file
188
src/modules/dayjs/plugin/timezone/index.js
Normal file
@@ -0,0 +1,188 @@
|
||||
/**
|
||||
* Copy from node_modules/dayjs/plugin/timezone.js
|
||||
* Try to fix https://github.com/louislam/uptime-kuma/issues/2318
|
||||
* Source: https://github.com/iamkun/dayjs/tree/dev/src/plugin/utc
|
||||
* License: MIT
|
||||
*/
|
||||
import { MIN, MS } from "../../constant";
|
||||
let typeToPos = {
|
||||
year: 0,
|
||||
month: 1,
|
||||
day: 2,
|
||||
hour: 3,
|
||||
minute: 4,
|
||||
second: 5
|
||||
}; // Cache time-zone lookups from Intl.DateTimeFormat,
|
||||
// as it is a *very* slow method.
|
||||
|
||||
let dtfCache = {};
|
||||
|
||||
let getDateTimeFormat = function getDateTimeFormat(timezone, options) {
|
||||
if (options === void 0) {
|
||||
options = {};
|
||||
}
|
||||
|
||||
let timeZoneName = options.timeZoneName || "short";
|
||||
let key = timezone + "|" + timeZoneName;
|
||||
let dtf = dtfCache[key];
|
||||
|
||||
if (!dtf) {
|
||||
dtf = new Intl.DateTimeFormat("en-US", {
|
||||
hour12: false,
|
||||
timeZone: timezone,
|
||||
year: "numeric",
|
||||
month: "2-digit",
|
||||
day: "2-digit",
|
||||
hour: "2-digit",
|
||||
minute: "2-digit",
|
||||
second: "2-digit",
|
||||
timeZoneName: timeZoneName
|
||||
});
|
||||
dtfCache[key] = dtf;
|
||||
}
|
||||
|
||||
return dtf;
|
||||
};
|
||||
|
||||
export default (function (o, c, d) {
|
||||
let defaultTimezone;
|
||||
|
||||
let makeFormatParts = function makeFormatParts(timestamp, timezone, options) {
|
||||
if (options === void 0) {
|
||||
options = {};
|
||||
}
|
||||
|
||||
let date = new Date(timestamp);
|
||||
let dtf = getDateTimeFormat(timezone, options);
|
||||
return dtf.formatToParts(date);
|
||||
};
|
||||
|
||||
let tzOffset = function tzOffset(timestamp, timezone) {
|
||||
let formatResult = makeFormatParts(timestamp, timezone);
|
||||
let filled = [];
|
||||
|
||||
for (let i = 0; i < formatResult.length; i += 1) {
|
||||
let _formatResult$i = formatResult[i];
|
||||
let type = _formatResult$i.type;
|
||||
let value = _formatResult$i.value;
|
||||
let pos = typeToPos[type];
|
||||
|
||||
if (pos >= 0) {
|
||||
filled[pos] = parseInt(value, 10);
|
||||
}
|
||||
}
|
||||
|
||||
let hour = filled[3]; // Workaround for the same behavior in different node version
|
||||
// https://github.com/nodejs/node/issues/33027
|
||||
|
||||
/* istanbul ignore next */
|
||||
|
||||
let fixedHour = hour === 24 ? 0 : hour;
|
||||
let utcString = filled[0] + "-" + filled[1] + "-" + filled[2] + " " + fixedHour + ":" + filled[4] + ":" + filled[5] + ":000";
|
||||
let utcTs = d.utc(utcString).valueOf();
|
||||
let asTS = +timestamp;
|
||||
let over = asTS % 1000;
|
||||
asTS -= over;
|
||||
return (utcTs - asTS) / (60 * 1000);
|
||||
}; // find the right offset a given local time. The o input is our guess, which determines which
|
||||
// offset we'll pick in ambiguous cases (e.g. there are two 3 AMs b/c Fallback DST)
|
||||
// https://github.com/moment/luxon/blob/master/src/datetime.js#L76
|
||||
|
||||
let fixOffset = function fixOffset(localTS, o0, tz) {
|
||||
// Our UTC time is just a guess because our offset is just a guess
|
||||
let utcGuess = localTS - o0 * 60 * 1000; // Test whether the zone matches the offset for this ts
|
||||
|
||||
let o2 = tzOffset(utcGuess, tz); // If so, offset didn't change and we're done
|
||||
|
||||
if (o0 === o2) {
|
||||
return [ utcGuess, o0 ];
|
||||
} // If not, change the ts by the difference in the offset
|
||||
|
||||
utcGuess -= (o2 - o0) * 60 * 1000; // If that gives us the local time we want, we're done
|
||||
|
||||
let o3 = tzOffset(utcGuess, tz);
|
||||
|
||||
if (o2 === o3) {
|
||||
return [ utcGuess, o2 ];
|
||||
} // If it's different, we're in a hole time.
|
||||
// The offset has changed, but the we don't adjust the time
|
||||
|
||||
return [ localTS - Math.min(o2, o3) * 60 * 1000, Math.max(o2, o3) ];
|
||||
};
|
||||
|
||||
let proto = c.prototype;
|
||||
|
||||
proto.tz = function (timezone, keepLocalTime) {
|
||||
if (timezone === void 0) {
|
||||
timezone = defaultTimezone;
|
||||
}
|
||||
|
||||
let oldOffset = this.utcOffset();
|
||||
let date = this.toDate();
|
||||
let target = date.toLocaleString("en-US", {
|
||||
timeZone: timezone
|
||||
}).replace("\u202f", " ");
|
||||
let diff = Math.round((date - new Date(target)) / 1000 / 60);
|
||||
let ins = d(target).$set(MS, this.$ms).utcOffset(-Math.round(date.getTimezoneOffset() / 15) * 15 - diff, true);
|
||||
|
||||
if (keepLocalTime) {
|
||||
let newOffset = ins.utcOffset();
|
||||
ins = ins.add(oldOffset - newOffset, MIN);
|
||||
}
|
||||
|
||||
ins.$x.$timezone = timezone;
|
||||
return ins;
|
||||
};
|
||||
|
||||
proto.offsetName = function (type) {
|
||||
// type: short(default) / long
|
||||
let zone = this.$x.$timezone || d.tz.guess();
|
||||
let result = makeFormatParts(this.valueOf(), zone, {
|
||||
timeZoneName: type
|
||||
}).find(function (m) {
|
||||
return m.type.toLowerCase() === "timezonename";
|
||||
});
|
||||
return result && result.value;
|
||||
};
|
||||
|
||||
let oldStartOf = proto.startOf;
|
||||
|
||||
proto.startOf = function (units, startOf) {
|
||||
if (!this.$x || !this.$x.$timezone) {
|
||||
return oldStartOf.call(this, units, startOf);
|
||||
}
|
||||
|
||||
let withoutTz = d(this.format("YYYY-MM-DD HH:mm:ss:SSS"));
|
||||
let startOfWithoutTz = oldStartOf.call(withoutTz, units, startOf);
|
||||
return startOfWithoutTz.tz(this.$x.$timezone, true);
|
||||
};
|
||||
|
||||
d.tz = function (input, arg1, arg2) {
|
||||
let parseFormat = arg2 && arg1;
|
||||
let timezone = arg2 || arg1 || defaultTimezone;
|
||||
let previousOffset = tzOffset(+d(), timezone);
|
||||
|
||||
if (typeof input !== "string") {
|
||||
// timestamp number || js Date || Day.js
|
||||
return d(input).tz(timezone);
|
||||
}
|
||||
|
||||
let localTs = d.utc(input, parseFormat).valueOf();
|
||||
|
||||
let _fixOffset = fixOffset(localTs, previousOffset, timezone);
|
||||
let targetTs = _fixOffset[0];
|
||||
let targetOffset = _fixOffset[1];
|
||||
|
||||
let ins = d(targetTs).utcOffset(targetOffset);
|
||||
ins.$x.$timezone = timezone;
|
||||
return ins;
|
||||
};
|
||||
|
||||
d.tz.guess = function () {
|
||||
return Intl.DateTimeFormat().resolvedOptions().timeZone;
|
||||
};
|
||||
|
||||
d.tz.setDefault = function (timezone) {
|
||||
defaultTimezone = timezone;
|
||||
};
|
||||
});
|
@@ -106,7 +106,13 @@ class Logger {
|
||||
}
|
||||
module = module.toUpperCase();
|
||||
level = level.toUpperCase();
|
||||
const now = dayjs.tz(new Date()).format();
|
||||
let now;
|
||||
if (dayjs.tz) {
|
||||
now = dayjs.tz(new Date()).format();
|
||||
}
|
||||
else {
|
||||
now = dayjs().format();
|
||||
}
|
||||
const formattedMessage = (typeof msg === "string") ? `${now} [${module}] ${level}: ${msg}` : msg;
|
||||
if (level === "INFO") {
|
||||
console.info(formattedMessage);
|
||||
|
@@ -122,7 +122,12 @@ class Logger {
|
||||
module = module.toUpperCase();
|
||||
level = level.toUpperCase();
|
||||
|
||||
const now = dayjs.tz(new Date()).format();
|
||||
let now;
|
||||
if (dayjs.tz) {
|
||||
now = dayjs.tz(new Date()).format();
|
||||
} else {
|
||||
now = dayjs().format();
|
||||
}
|
||||
const formattedMessage = (typeof msg === "string") ? `${now} [${module}] ${level}: ${msg}` : msg;
|
||||
|
||||
if (level === "INFO") {
|
||||
|
Reference in New Issue
Block a user