Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support date/time on @colyseus/schema #297

Open
dengzhaofun opened this issue Jan 28, 2020 · 11 comments
Open

Support date/time on @colyseus/schema #297

dengzhaofun opened this issue Jan 28, 2020 · 11 comments
Labels
🧮 @colyseus/schema Problems related to Schema Serializer 🚀 feature
Milestone

Comments

@dengzhaofun
Copy link

Error: a 'string' was expected, but '"2020-01-28T15:33:25.708Z"' (Date) was provided in User#loginAt

@type('string')
@column({comment: '最后登录时间'})
loginAt: Date; // not work

@type('number')
@column({comment: '最后登录时间'})
loginAt: Date; // not work

@endel
Copy link
Member

endel commented Jan 28, 2020

Hi @dengzhaofun, Date is not supported as a type. You should use a timestamp instead. e.g. Date.now() or date.getTime()

@endel endel closed this as completed Jan 28, 2020
@dengzhaofun
Copy link
Author

dengzhaofun commented Jan 28, 2020

Why not support the Date type, even if it helps to convert the number to display on the client. Forcing developers to change the data types of existing code is not a good solution @endel

@endel
Copy link
Member

endel commented Jan 28, 2020

Supporting Date in the future would be nice indeed, let's keep this issue open until we have it!

@endel endel reopened this Jan 28, 2020
@endel endel added 🧮 @colyseus/schema Problems related to Schema Serializer 🚀 feature labels Jan 28, 2020
@endel endel added this to the 0.15.0 milestone Oct 20, 2020
@vitalyrotari
Copy link

@endel @type('string') is casting to string?

I use moment/luxon for date & time

import { DateTime, Duration } from "luxon";

DateTime.now().toString();  // 2021-03-05T19:26:46.628+02:00
Duration.fromMillis(30000).toString(); // PT30S

In my opinion Date is very primitive

(new Date()).toString(); // Fri Mar 05 2021 19:31:51 GMT+0200 (Eastern European Standard Time)

@endel
Copy link
Member

endel commented Mar 5, 2021

I'd prefer sending dates as number/unix timestamp rather than strings @vitalyrotari:

class State extends Schema {
  @type("number") timestamp: number;
}

const state = new State();
state.timestamp = Date.now(); 
// => 1614970340065

const dateInstance = new Date(state.timestamp);
// => Fri Mar 05 2021 15:52:20 GMT-0300 (Brasilia Standard Time)

dateInstance.getTime() === state.timestamp
// => true

Eventually would be nice to convert seamlessly from unix timestamp to Date objects tho - the reason for not using strings from my perspective are that strings would consume slightly more data to transfer, and that unix timestamp is a format most client-side targets could easily convert into their own Date/DateTime object easily, for example:

@vitalyrotari
Copy link

@endel unix timestamp doesn't preserve time zone, this is why I use ISO 8601. So if timezone is not critical, yes we can use unix timestamp :)

@endel
Copy link
Member

endel commented Mar 5, 2021

@vitalyrotari I think it does! check out this answer on Stack Overflow: https://stackoverflow.com/questions/23062515/do-unix-timestamps-change-across-timezones/23062640#23062640

"The definition of UNIX timestamp is timezone independent. The timestamp is the number of seconds (or milliseconds) elapsed since an absolute point in time, midnight of Jan 1 1970 in UTC time. (UTC is Greenwich Mean Time without Daylight Savings time adjustments.) Regardless of your timezone, a timestamp represents a moment that is the same everywhere. Of course you can convert back and forth to a local timezone representation (time 1397484936 is such-and-such local time in New York, or some other local time in Djakarta) if you want"

@endel
Copy link
Member

endel commented Mar 5, 2021

Oh I understand what you mean now, it is the same time but it does not specify which timezone that time is, that's right!

@vitalyrotari
Copy link

@endel yep :) So the bulletproof option is ISO 8601, but that's if accuracy is required.

@endel endel added this to 📚 Backlog in Next version (0.15) via automation Aug 19, 2021
@endel endel modified the milestones: 0.15, 1.0 May 5, 2023
@endel endel changed the title Schema how to support date type Support date/time on @colyseus/schema May 5, 2023
@hunkydoryrepair
Copy link
Contributor

hunkydoryrepair commented Jan 5, 2024

But, Date object in javascript doesn't preserve timezone, either.
So if you want ISO with timezone, you need to use a string. Date object doesn't help you. Converting Date => string => Date will not provide timezone information as you can only get UTC or local time from a Date object.

@hunkydoryrepair
Copy link
Contributor

@endel perhaps what is needed is a more generic solution, which is custom serializer/deserializer types. Would need to be registered on client to deserialize, matching the provided decorator.

Might let you do:

Schema.registerSerializer('datetime', (o) => o.toString()); // support string or uIntarray

@type('datetime') MyDate: DateTime;

Schema.regiseterDeserializer('datetime', (s) => new DateTime(s));

of course, this would not serialize internal changes to the object and would only support updates by replacing the full object using the setter. And requires sending full data, unless you want to scan the byte array for diffs and only send the parts that change.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🧮 @colyseus/schema Problems related to Schema Serializer 🚀 feature
Projects
No open projects
Development

No branches or pull requests

4 participants