Orbito - Dokumentacja modułówOrbito - Dokumentacja modułów
Wprowadzenie
Pierwsze kroki
API
Komunikacja
Widoki
Wdrożenie
Społeczność
For AI agents
Wprowadzenie
Pierwsze kroki
API
Komunikacja
Widoki
Wdrożenie
Społeczność
For AI agents
  • API biblioteki

    • API biblioteki @orbito/api-lib
    • Core
    • Log
    • Utils
    • Pages
    • Automation
    • DB
    • Config
    • Files
    • Problems
    • History
    • OAuth
    • Time
    • Mail
    • Templates
    • Lock
    • Uprawnienia

Time

Moduł Time daje helpery do dat w strefie czasowej firmy: parsowanie, formatowanie, granice dnia i dodawanie dni kalendarzowych, bez zależności od TZ kontenera ani od przeglądarki (od SDK 4.3.0).

const { Time } = require('@orbito/api-lib');

Time.inZone(timeZone)    // -> helpery dla wskazanej strefy (synchronicznie)
Time.forCompany()        // -> Promise helperów dla strefy firmy

Po co to jest

Moduł działa w kontenerze, którego lokalna strefa czasowa nic nie mówi o firmie. „Dziś”, „zamówienia z 2026-10-06” czy „termin płatności za 14 dni” oznaczają dzień roboczy firmy, czyli strefę ustawioną przez jej administratora (Core.getCompany().timezone, nazwa IANA, domyślnie Europe/Warsaw). Każdy helper przyjmuje strefę jawnie, więc nic nie jest przybite do jednej strefy i nic nie czyta process.env.TZ.

Wspólna semantyka wszystkich helperów:

  • znacznik z offsetem (Z, +02:00), Date i liczba milisekund zachowują swoją chwilę. Tekst bez offsetu (2026-10-06 14:30, 2026-10-06) oznacza czas w strefie, nigdy lokalny czas kontenera,
  • godzina, która nie istnieje w strefie (wiosenna luka przy zmianie czasu), jest nieprawidłowa (null), a godzina występująca dwa razy (jesienne cofnięcie) daje swoje pierwsze wystąpienie,
  • dni są kalendarzowe: przy zmianie czasu dzień trwa 23 lub 25 godzin, więc „+1 dzień” to nigdy „+24 h”.

Time.inZone

Zwraca helpery dla wskazanej strefy. Funkcja jest synchroniczna i czysta. Zwrócony obiekt jest zamrożony i współdzielony przez wszystkich proszących o tę samą strefę, więc można go bezpiecznie przekazywać dalej. Intl.DateTimeFormat strefy powstaje raz, dlatego wielokrotne wołanie jest tanie.

const warsaw = Time.inZone('Europe/Warsaw');
warsaw.parseDate('2026-10-06 14:30');           // 2026-10-06T12:30:00.000Z
warsaw.formatDate(new Date(), 'YYYY-MM-DD');    // dzisiaj w Warszawie
ParametrTypOpis
timeZonestringNazwa strefy IANA, np. Europe/Warsaw

Pusta lub nieznana strefa rzuca RangeError (Invalid time zone specified: ...).

Zwrócony obiekt zawiera timeZone (strefa tak, jak ją podano) oraz funkcje:

HelperOpis
parseDate(value)Zwraca Date albo null. Przyjmuje Date, liczbę milisekund lub tekst YYYY-MM-DD, opcjonalnie z HH:mm[:ss[.fff]] lub THH:mm..., opcjonalnie z Z/±HH:mm. null dla nieprawidłowej daty i godziny z wiosennej luki
formatDate(value, pattern)Tekst w strefie. Tokeny: YYYY MM DD HH mm ss, reszta jest kopiowana. Domyślny wzorzec to DD.MM.YYYY HH:mm. Zwraca '', gdy value się nie parsuje
dateBoundary(value, endOfDay)Dla YYYY-MM-DD początek (00:00:00.000) albo koniec (23:59:59.999, gdy endOfDay to true) tego dnia w strefie. Każda inna wartość jest parsowana jak w parseDate
addCalendarDays(value, days)Dzień kalendarzowy value w strefie przesunięty o days dni, jako YYYY-MM-DD (bezpieczne przy zmianie czasu). Zwraca '' dla nieprawidłowego wejścia
const ny = Time.inZone('America/New_York');
ny.parseDate('2026-10-06 09:00');                // 2026-10-06T13:00:00.000Z
ny.formatDate('2026-10-06T13:00:00Z');           // '06.10.2026 09:00'
ny.addCalendarDays('2026-10-06T13:00:00Z', 14);  // '2026-10-20'

Time.forCompany

Zwraca Promise helperów dla bieżącej strefy firmy, czyli Time.inZone ze strefą z Core.getCompany(). Przy każdym wywołaniu pyta rdzeń (bez cache i bez powiadomień o zmianie), a gdy Core.getCompany() odrzuci Promise, odrzuca go również.

const time = await Time.forCompany();

Zalecany wzorzec

Pobierz strefę raz na początku handlera metody lub hooka i przekaż helpery w dół do kodu synchronicznego (budowanie zapytań, formatowanie):

const { Core, DB, Time } = require('@orbito/api-lib');

Core.registerMethod('orders.list', async (params) => {
    const time = await Time.forCompany(); // raz na wywołanie, potem przekazywane w dół
    return DB.find('orders', buildQuery(params, time));
});

// funkcja synchroniczna dostaje helpery zamiast czytać globalną strefę
function buildQuery({ dateFrom, dateTo }, time) {
    return {
        createdAt: {
            $gte: time.dateBoundary(dateFrom),       // 00:00:00 tego dnia w strefie firmy
            $lte: time.dateBoundary(dateTo, true)    // 23:59:59.999 tego dnia
        }
    };
}

Termin płatności liczony w dniach kalendarzowych firmy:

Core.registerMethod('payments.dueDate', async ({ issuedAt, termDays }) => {
    const time = await Time.forCompany();
    return { dueDate: time.addCalendarDays(issuedAt, termDays) };
});

Czego nie robić

Nie trzymaj helperów w zmiennej modułu

Administrator może zmienić strefę w każdej chwili. Wartość pobrana przy starcie kontenera po cichu się zestarzeje. Wołaj Time.forCompany() w handlerze, a nie na poziomie modułu.

Nie czytaj process.env.TZ

TZ kontenera nie ma związku ze strefą firmy. Nie używaj też metod Date zależnych od lokalnej strefy (getHours, toLocaleString bez timeZone, new Date('2026-10-06 14:30')), tylko helperów z tego rozdziału. Gdy potrzebujesz stałej strefy (np. w testach albo strefy dostawcy), użyj Time.inZone('...') z jawną nazwą.

Ostatnio zaktualizowano:: 6.10.2026, 12:34
Contributors: Wiktor Koźmiński, Claude Fable 5.1
Prev
OAuth
Next
Mail