0

I have an admin panel where items entered will have a time_posted and an expiration time. These times use a timestamp (time()) upon being entered.

I want the entering of the expiration time to use a fancy date/time selector, but the selector uses JavaScript client time rather than server time.

A way to fix this would be to save the timezone a user is in, then use that as offset for the data entered, but it's something that has to be 100% correct.

Is there any 'proper' way to approach this? I saw that some PHP functions do use the timezone setting but others do not, for instance the actual time() function doesn't and even if I create a DateTime object, output the current timestamp, change the timezone and output the timestamp again it just returns the same timestamp twice.

Any pointers would be lovely

Ieuan
  • 1,042
  • 1
  • 12
  • 26
  • 1
    `time()` returns an Unix timestamp and this timestamp is independent from timezones. – Roland Starke Sep 02 '16 at 10:38
  • That is not my question though, my question is about using offsets server-side to get the correct Unix timestamp from the local timestamp the client sends based on the account's saved timezone – Ieuan Sep 02 '16 at 10:39
  • Get the fancy date selector to give you a UNIX timestamp/Javascript `Date` object from which you can get the timezone-independent UNIX timestamp. – deceze Sep 02 '16 at 10:40
  • What "fancy date/time selector" are you considering? For this application, you absolutely need a date/time selector that's initialized from server time rather than from browser time (client-side time). Client side time simply isn't reliable enough. – O. Jones Sep 02 '16 at 10:45
  • I'm using some admin panel theme which seems to include a modified version of http://trentrichardson.com/examples/timepicker/. It seems like it doesn't even return a timestamp but rather a string of the selected time. I could just use this string + saved timezone I guess? – Ieuan Sep 02 '16 at 10:53
  • @RolandStarke: it's not "independent". it's just always UTC-0 – Marc B Sep 02 '16 at 16:41

2 Answers2

2

I assume that the actual timestamp value would still be correct (independent) regardless of what settings/timezone the end user has.

Problems may apper when/if you want to generate date strings server-side and thus return times with offsets.

Either 1. dont generate date strings server side, if you are not sure about the timezone offsets or 2. warn users and make sure that they specify their timezone and then force that timezone whenever you output date string from timestamps

kitaps
  • 233
  • 3
  • 10
  • The problem is mostly that the value saved needs to be a unix timestamp (obviously). I need a way to convert from the client time to a unix timestamp and from a unix timestamp I need to display the time in the user's timezone. Is it really as simple as just saving the Unix timestamp and then using a DateTime object to display? – Ieuan Sep 02 '16 at 10:42
  • yep, its that simple. If you want to display times depending on the end users computer time, just do it in javascript. I dont know the details, but i would assume that it would be safer to set/store the user specified timezone. So that when the same user or someone else logs in from a computer with different timezone, the times displayed still match the original input. – kitaps Sep 02 '16 at 10:50
1

A few things:

  • You probably don't need to identify the user's time zone for the scenario you describe, but if you did then please recognize that a time zone and an offset are two different things. See "time zone != offset" in the timezone tag wiki. If you actually think you need the user's time zone (such as "America/Los_Angeles"), then refer to this answer.

  • If you want the entered date to be relative to the client's local time zone, then you need to use either a Date object, or a library like moment.js in JavaScript. Use the individual date/time components from the date picker to get either a unix timestamp, or an ISO8601 formatted date/time string at UTC. For example, "2016-09-02T01:23:45Z"

  • If you want the entered date to be relative to some other time zone, then you need to transmit the actual values the client entered without modification. The best way is in ISO8601 format without offset. For example, "2016-09-02T08:00:00". On the server side, parse that value and apply whatever time zone is applicable.

  • If you are only selecting a date, and not a time, then you should really think about whether any time is applicable or not. Is 00:00 really applicable? Or should it be 24:00 or 23:59:59.999? If you don't care about the user's time zone, then really you shouldn't assign any time value at all. Just pass the date. For example: "2016-09-02"

  • Don't rely on the server's time zone setting to be anything in particular. Though PHP has functionality for setting a "default" time zone, you should try to avoid using it. It is much safer to be explicit about time zones on a per-operation basis. Use the DateTime class in PHP, not time().

Be sure to read Daylight saving time and time zone best practices, and to search thoroughly for other questions on StackOverflow, as much of this has been answered already in various other questions.

Community
  • 1
  • 1
Matt Johnson-Pint
  • 197,368
  • 66
  • 382
  • 508
  • I definitely need offset and not timezones for displaying the timezones to the users, but making them select the offset by picking their timezone in their profile settings is a lot easier for them than having them enter an offset. Thanks for the other pointers. – Ieuan Sep 02 '16 at 17:34
  • Just be careful - you cannot get the current offset and assume that it applies to all points in time. Many make this mistake. Daylight Saving Time will get in the way. – Matt Johnson-Pint Sep 02 '16 at 17:36
  • But if I use DateTimeZone/DateTime to format the dates that should be fine right? Set the timestamp, set the timezone then format? – Ieuan Sep 02 '16 at 17:55
  • Depends on how you gather the timestamp. Hard to say with how you've currently presented things. Give it a try and if you get stuck then post a new question with details. – Matt Johnson-Pint Sep 02 '16 at 18:04
  • Well realistically I've not set up anything, the timestamps in the database now (time posted) are just PHP's `time()`. I'll give it a shot and if I can't figure it out you'll see a new question pop up in a couple hours! Thanks so far! – Ieuan Sep 02 '16 at 18:18
  • Read: [How to create a Minimal, Complete, and Verifiable example](http://stackoverflow.com/help/mcve) – Matt Johnson-Pint Sep 02 '16 at 19:35