[#6688] added optional timezone identifier argument to the JSVM DateTime constructor
This commit is contained in:
parent
5d32d22ff5
commit
0efbbb0d10
11
CHANGELOG.md
11
CHANGELOG.md
|
@ -1,6 +1,6 @@
|
|||
## v0.27.0 (WIP)
|
||||
|
||||
- ⚠️ Moved the Create and Manage API rule checks out of the `OnRecordCreateRequest` hook finalizer, **aka. now all API rules are checked BEFORE triggering their corresponding `*Request` hook**.
|
||||
- ⚠️ Moved the Create and Manage API rule checks out of the `OnRecordCreateRequest` hook finalizer, **aka. now all CRUD API rules are checked BEFORE triggering their corresponding `*Request` hook**.
|
||||
This was done to minimize the confusion regarding the firing order of the request operations, making it more predictable and consistent with the other record List/View/Update/Delete request actions.
|
||||
It could be a minor breaking change if you are relying on the old behavior or have a Go `tests.ApiScenario` that is testing a Create API rule failure and expect `OnRecordCreateRequest` to be fired. In that case for example you may have to update your test scenario like:
|
||||
```go
|
||||
|
@ -28,6 +28,15 @@
|
|||
|
||||
- Forced `text/javascript` Content-Type when serving `.js`/`.mjs` collection uploaded files ([#6597](https://github.com/pocketbase/pocketbase/issues/6597)).
|
||||
|
||||
- Added optional timezone argument to the JSVM `DateTime` constructor to parse the date string in the specified TZ identifier in order to better handle the daylight saving time nuances ([#6688](https://github.com/pocketbase/pocketbase/discussions/6688)):
|
||||
```
|
||||
// the same as with CET offset: new DateTime("2025-10-26 03:00:00 +01:00")
|
||||
new DateTime("2025-10-26 03:00:00", "Europe/Amsterdam") // 2025-10-26 02:00:00.000Z
|
||||
|
||||
// the same as with CEST offset: new DateTime("2025-10-26 01:00:00 +02:00")
|
||||
new DateTime("2025-10-26 01:00:00", "Europe/Amsterdam") // 2025-10-25 23:00:00.000Z
|
||||
```
|
||||
|
||||
- Soft-deprecated the `$http.send`'s `result.raw` field in favor of `result.body` that contains the response body as plain bytes slice to avoid the discrepancies between Go and the JSVM when casting binary data to string.
|
||||
(@todo update docs to use the new field)
|
||||
|
||||
|
|
|
@ -548,9 +548,18 @@ func baseBinds(vm *goja.Runtime) {
|
|||
vm.Set("DateTime", func(call goja.ConstructorCall) *goja.Object {
|
||||
instance := types.NowDateTime()
|
||||
|
||||
val, _ := call.Argument(0).Export().(string)
|
||||
if val != "" {
|
||||
instance, _ = types.ParseDateTime(val)
|
||||
rawDate, _ := call.Argument(0).Export().(string)
|
||||
locName, _ := call.Argument(1).Export().(string)
|
||||
if rawDate != "" && locName != "" {
|
||||
loc, err := time.LoadLocation(locName)
|
||||
if err != nil {
|
||||
loc = time.UTC
|
||||
}
|
||||
|
||||
instance, _ = types.ParseDateTime(cast.ToTimeInDefaultLocation(rawDate, loc))
|
||||
} else if rawDate != "" {
|
||||
// forward directly to ParseDateTime to preserve the original behavior
|
||||
instance, _ = types.ParseDateTime(rawDate)
|
||||
}
|
||||
|
||||
instanceValue := vm.ToValue(instance).(*goja.Object)
|
||||
|
|
|
@ -568,15 +568,35 @@ func TestBaseBindsDateTime(t *testing.T) {
|
|||
baseBinds(vm)
|
||||
|
||||
_, err := vm.RunString(`
|
||||
const v0 = new DateTime();
|
||||
if (v0.isZero()) {
|
||||
throw new Error('Expected to fallback to now, got zero value');
|
||||
const now = new DateTime();
|
||||
if (now.isZero()) {
|
||||
throw new Error('(now) Expected to fallback to now, got zero value');
|
||||
}
|
||||
|
||||
const v1 = new DateTime('2023-01-01 00:00:00.000Z');
|
||||
const expected = "2023-01-01 00:00:00.000Z"
|
||||
if (v1.string() != expected) {
|
||||
throw new Error('Expected ' + expected + ', got ', v1.string());
|
||||
const nowPart = now.string().substring(0, 19)
|
||||
|
||||
const scenarios = [
|
||||
// empty datetime string and no custom location
|
||||
{date: new DateTime(''), expected: nowPart},
|
||||
// empty datetime string and custom default location (should be ignored)
|
||||
{date: new DateTime('', 'Asia/Tokyo'), expected: nowPart},
|
||||
// full datetime string and no custom default location
|
||||
{date: new DateTime('2023-01-01 00:00:00.000Z'), expected: "2023-01-01 00:00:00.000Z"},
|
||||
// invalid location (fallback to UTC)
|
||||
{date: new DateTime('2025-10-26 03:00:00', 'invalid'), expected: "2025-10-26 03:00:00.000Z"},
|
||||
// CET
|
||||
{date: new DateTime('2025-10-26 03:00:00', 'Europe/Amsterdam'), expected: "2025-10-26 02:00:00.000Z"},
|
||||
// CEST
|
||||
{date: new DateTime('2025-10-26 01:00:00', 'Europe/Amsterdam'), expected: "2025-10-25 23:00:00.000Z"},
|
||||
// with timezone/offset in the date string (aka. should ignore the custom default location)
|
||||
{date: new DateTime('2025-10-26 01:00:00 +0200', 'Asia/Tokyo'), expected: "2025-10-25 23:00:00.000Z"},
|
||||
];
|
||||
|
||||
for (let i = 0; i < scenarios.length; i++) {
|
||||
const s = scenarios[i];
|
||||
if (!s.date.string().includes(s.expected)) {
|
||||
throw new Error('(' + i + ') ' + s.date.string() + ' does not contain expected ' + s.expected);
|
||||
}
|
||||
}
|
||||
`)
|
||||
if err != nil {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -608,19 +608,27 @@ declare class Timezone implements time.Location {
|
|||
interface DateTime extends types.DateTime{} // merge
|
||||
/**
|
||||
* DateTime defines a single DateTime type instance.
|
||||
* The returned date is always represented in UTC.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* ` + "```" + `js
|
||||
* const dt0 = new DateTime() // now
|
||||
*
|
||||
* // full datetime string
|
||||
* const dt1 = new DateTime('2023-07-01 00:00:00.000Z')
|
||||
*
|
||||
* // datetime string with default "parse in" timezone location
|
||||
* //
|
||||
* // similar to new DateTime('2023-07-01 00:00:00 +01:00') or new DateTime('2023-07-01 00:00:00 +02:00')
|
||||
* // but accounts for the daylight saving time (DST)
|
||||
* const dt2 = new DateTime('2023-07-01 00:00:00', 'Europe/Amsterdam')
|
||||
* ` + "```" + `
|
||||
*
|
||||
* @group PocketBase
|
||||
*/
|
||||
declare class DateTime implements types.DateTime {
|
||||
constructor(date?: string)
|
||||
constructor(date?: string, defaultParseInLocation?: string)
|
||||
}
|
||||
|
||||
interface ValidationError extends ozzo_validation.Error{} // merge
|
||||
|
|
Loading…
Reference in New Issue