moment / luxon

⏱ A library for working with dates and times in JS
https://moment.github.io/luxon
MIT License
15.27k stars 732 forks source link

Rehydrate/recreate Luxon object (structural cloning) #1125

Open florianbepunkt opened 2 years ago

florianbepunkt commented 2 years ago

Is your feature request related to a problem? Please describe. I'm using luxon in Electron. After sending luxon objects via IPC, all prototype methods are lost, since IPC uses structural cloning.

So the data is still there (see below), but you cannot call methods on it.

{
    "ts": 1632952800000,
    "_zone": {},
    "loc": {
        "locale": "de",
        "numberingSystem": null,
        "outputCalendar": null,
        "intl": "de",
        "weekdaysCache": {
            "format": {},
            "standalone": {}
        },
        "monthsCache": {
            "format": {},
            "standalone": {}
        },
        "meridiemCache": null,
        "eraCache": {},
        "specifiedLocale": null,
        "fastNumbersCached": null
    },
    "invalid": null,
    "weekData": null,
    "c": {
        "year": 2021,
        "month": 9,
        "day": 30,
        "hour": 0,
        "minute": 0,
        "second": 0,
        "millisecond": 0
    },
    "o": 120,
    "isLuxonDateTime": true
}

Describe the solution you'd like A way to create a DateTime from a DateTime obj or another way to rehydrate the DateTime.

Describe alternatives you've considered Do some custom serialization, but I would like to avoid this since we use custom Codecs for validation. Recreating the DateTime from the timestamp (ts)

Additional context Add any other context or screenshots about the feature request here.

icambron commented 2 years ago

Let me make sure I understand your request: you would like a function that takes in a plain ol javascript object, presumably a serialized-and-then-deserialized DateTime instance, and returns a DateTime?

florianbepunkt commented 2 years ago

Yes, exactly.

icambron commented 2 years ago

That would require a bit of mucking with the DateTime constructor, which is a little messy. But it's a reasonable request; I'd take a crisp PR that does this

tobad357 commented 2 years ago

We have a similar need when using Cloudflare Durable Objects and Cloudflare KV store which does structural cloning. Would be very helpful it we didn't have to JSON.parse and JSON.stringify each item we store

cphillips commented 7 months ago

This feature is also useful for passing Luxon DateTime to web workers.

EvaLok commented 1 month ago

i'm not sure if this is comprehensive enough, but something like this could work

import { DateTime, Duration } from "luxon"

/**
 * recursively restores luxon objects present within a given object
 */
export function restoreLuxonObjects( obj: any ) {
    for ( const k in obj ) {
        if ( ! obj.hasOwnProperty(k) ) {
            continue
        }

        if (typeof obj[k] === "object" && obj[k] !== null) {
            if (obj[k].hasOwnProperty('isLuxonDateTime')) {
                obj[k] = DateTime.fromMillis(obj[k].ts)
                continue
            }

            if (obj[k].hasOwnProperty('isLuxonDuration')) {
                obj[k] = Duration.fromObject(obj[k].values)
                continue
            }

            restoreLuxonObjects(obj[k])
        }
    }
}