[Catalyst] User timezones
Hi Everybody, I wonder how you handle user-specific timezones in Catalyst. Our application is used by customers in various locations, and thus timezones. I would now like to be able to specify the user's timezone in his database entry and then show all times to her accordingly. Most of the time data is stored in the database (also show some filesystem dates at other places, and there are probably more sources, but let's concentrate on the database first). Is there a way to handle this transparently? If I use inflation/deflation (as does DBIx::Class::DateTime for instance), I could handle the conversion transparently, however, since the timezone depends on the user, I cannot define it in the DBIx add_columns() definition. And manually adjusting the timezone after the data leaves the Model is probably no good idea either (to easy to forget something or make a mistake). Is there any magic switch I could set (for instance if the user is authorized or the session restored) to automatically get the right time for the user? Christian ___ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] User timezones
I would store it in whatever user profile set up you have for each user. you could simply create a column and add the GMT offset. On Thu, Jun 25, 2009 at 12:19 AM, Christian Lackas wrote: > Hi Everybody, > > I wonder how you handle user-specific timezones in Catalyst. > > Our application is used by customers in various locations, and thus > timezones. I would now like to be able to specify the user's timezone in > his database entry and then show all times to her accordingly. > Most of the time data is stored in the database (also show some > filesystem dates at other places, and there are probably more sources, > but let's concentrate on the database first). > Is there a way to handle this transparently? If I use > inflation/deflation (as does DBIx::Class::DateTime for instance), > I could handle the conversion transparently, however, since the timezone > depends on the user, I cannot define it in the DBIx add_columns() > definition. And manually adjusting the timezone after the data leaves > the Model is probably no good idea either (to easy to forget something > or make a mistake). > > Is there any magic switch I could set (for instance if the user is > authorized or the session restored) to automatically get the right time > for the user? > > Christian > > > ___ > List: Catalyst@lists.scsys.co.uk > Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst > Searchable archive: > http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ > Dev site: http://dev.catalyst.perl.org/ > -- Devin Austin http://www.codedright.net http://www.dreamhost.com/r.cgi?326568/hosting.html - Host with DreamHost! ___ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] User timezones
* Devin Austin [090625 08:25]: Hi Devin, > > I wonder how you handle user-specific timezones in Catalyst. > > Is there any magic switch I could set (for instance if the user is > > authorized or the session restored) to automatically get the right time > > for the user? > I would store it in whatever user profile set up you have for each user. > you could simply create a column and add the GMT offset. thanks for your quick reply, and every user entry in the database already has a timezone field. The low level mechanics are not so much of a problem. However, I don't want to do this everywhere I access a date column from the database (basically every table has a creation timestamp, many also for deletion or last change). What I am looking for, is a transparent way to set a timezone for the rest of the request (for instance when the session is restored and thus Catalyst knows which user it is dealing with) and then inflate/deflate should automatically convert timezones from/to UTC automatically. My hope was that somebody has already solved this problem or has an idea on how to approach it efficiently. Christian -- http://www.invicro.com/ ___ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] User timezones
On Thu, Jun 25, 2009 at 1:34 AM, Christian Lackas wrote: > * Devin Austin [090625 08:25]: > > Hi Devin, > > > > I wonder how you handle user-specific timezones in Catalyst. > > > Is there any magic switch I could set (for instance if the user is > > > authorized or the session restored) to automatically get the right time > > > for the user? > > I would store it in whatever user profile set up you have for each user. > > you could simply create a column and add the GMT offset. > > thanks for your quick reply, and every user entry in the database > already has a timezone field. > The low level mechanics are not so much of a problem. However, I don't > want to do this everywhere I access a date column from the database > (basically every table has a creation timestamp, many also for deletion > or last change). > What I am looking for, is a transparent way to set a timezone for the > rest of the request (for instance when the session is restored and thus > Catalyst knows which user it is dealing with) and then inflate/deflate > should automatically convert timezones from/to UTC automatically. > My hope was that somebody has already solved this problem or has an idea > on how to approach it efficiently. > > Christian > > -- > http://www.invicro.com/ > > ___ > List: Catalyst@lists.scsys.co.uk > Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst > Searchable archive: > http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ > Dev site: http://dev.catalyst.perl.org/ > I have to be honest, I'm not sure I understand. Perhaps I'm missing something. I would approach it so that when the user registers, they choose their time zone. When they login, this information is stored into their session, and retrieved whenever. I would store it in the session in the form you want it to be presented, which would save you whatever time it would take to be inflating it. If i'm still misunderstanding, please elaborate and maybe I can poke at it some more. hth, -devin -- Devin Austin http://www.codedright.net http://www.dreamhost.com/r.cgi?326568/hosting.html - Host with DreamHost! ___ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] User timezones
* Devin Austin [090625 09:43]: Hi Devin, > I would approach it so that when the user registers, they choose their time > zone. When they login, this information is stored into their session, and > retrieved whenever. agreed. > I would store it in the session in the form you want it to be > presented, which would save you whatever time it would take to be > inflating it. Now the problem begins: I have tables for studies, series and images (and many more), each of them has multiple timestamps (e.g. when the study was created, the series acquired, the image processed, and when everything was created and deleted). So when I access all these times, I would have to convert all of them, e.g. in a template [% study.time.convertTZ(c.user) %] [% series.time.convertTZ(c.user) %] rather than just use (after Catalyst knows about the users timezone, somehow). [% study.time %] [% series.time %] and I must not miss a single value. And things get even more complicated when I filter for times (e.g. show images created in the last 3 hours), or if I want to show only datasets whose deletion date is in the past (could have be deleted in Europe and should also be gone in the US). I do know how to do all these things manually one by one, however, I already foresee that I will miss TZ conversions somewhere or accidentally do it twice in wrong direction, or ... I also know how to use inflation/deflation to a DateTime, which allows me to specify ONE timezone in the Model, however, how do I change the timezone on a per-user basis. Christian -- http://www.invicro.com/ ___ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] User timezones
On Thu, Jun 25, 2009 at 1:54 AM, Christian Lackas wrote: > * Devin Austin [090625 09:43]: > > Hi Devin, > > > I would approach it so that when the user registers, they choose their > time > > zone. When they login, this information is stored into their session, and > > retrieved whenever. > > agreed. > > > I would store it in the session in the form you want it to be > > presented, which would save you whatever time it would take to be > > inflating it. > > Now the problem begins: > I have tables for studies, series and images (and many more), each of > them has multiple timestamps (e.g. when the study was created, the > series acquired, the image processed, and when everything was created > and deleted). > So when I access all these times, I would have to convert all of them, > e.g. in a template > >[% study.time.convertTZ(c.user) %] >[% series.time.convertTZ(c.user) %] > > rather than just use (after Catalyst knows about the users timezone, > somehow). > >[% study.time %] >[% series.time %] > > and I must not miss a single value. And things get even more complicated > when I filter for times (e.g. show images created in the last 3 hours), > or if I want to show only datasets whose deletion date is in the past > (could have be deleted in Europe and should also be gone in the US). > > I do know how to do all these things manually one by one, however, I > already foresee that I will miss TZ conversions somewhere or > accidentally do it twice in wrong direction, or ... > > I also know how to use inflation/deflation to a DateTime, which allows > me to specify ONE timezone in the Model, however, how do I change the > timezone on a per-user basis. > > Christian > > -- > http://www.invicro.com/ > > ___ > List: Catalyst@lists.scsys.co.uk > Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst > Searchable archive: > http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ > Dev site: http://dev.catalyst.perl.org/ > Hi Christian, Now the problem begins: > I have tables for studies, series and images (and many more), each of > them has multiple timestamps (e.g. when the study was created, the > series acquired, the image processed, and when everything was created > and deleted). > So when I access all these times, I would have to convert all of them, > e.g. in a template There we go, that's better :-) Check this out: http://search.cpan.org/~dkamholz/Catalyst-Plugin-Session-PerUser-0.03/lib/Catalyst/Plugin/Session/PerUser.pm That should allow you to stuff things into your session *per user*. I know this doesn't exactly help with converting each timestamp, but it's a start. I mean, you're going to have to retrieve each record per user anyway, why not retrieve, convert, and stuff it into the per-user session? -- Devin Austin http://www.codedright.net http://www.dreamhost.com/r.cgi?326568/hosting.html - Host with DreamHost! ___ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] User timezones
* Devin Austin [090625 10:12]: Hi Devin, > Check this out: > http://search.cpan.org/~dkamholz/Catalyst-Plugin-Session-PerUser-0.03/lib/Catalyst/Plugin/Session/PerUser.pm unfortuantely, I don't have any issues with my session management, which this module could help me with. My issue is with the model. The models inflation/deflation to/from DateTime objects should depend on the current user (namely her timezone property). > I mean, you're going to have to retrieve each record per user anyway, > why not retrieve, convert, and stuff it into the per-user session? I cannot store all these times in the session, since I have a few million database entries that all have different timestamps, that should be converted transparently whenever I need them. Christian -- http://www.invicro.com/ ___ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] User timezones
Am 25.06.2009 um 09:54 schrieb Christian Lackas: * Devin Austin [090625 09:43]: Hi Devin, I would approach it so that when the user registers, they choose their time zone. When they login, this information is stored into their session, and retrieved whenever. agreed. I would store it in the session in the form you want it to be presented, which would save you whatever time it would take to be inflating it. Now the problem begins: I have tables for studies, series and images (and many more), each of them has multiple timestamps (e.g. when the study was created, the series acquired, the image processed, and when everything was created and deleted). So when I access all these times, I would have to convert all of them, e.g. in a template [% study.time.convertTZ(c.user) %] [% series.time.convertTZ(c.user) %] rather than just use (after Catalyst knows about the users timezone, somehow). [% study.time %] [% series.time %] and I must not miss a single value. And things get even more complicated when I filter for times (e.g. show images created in the last 3 hours), or if I want to show only datasets whose deletion date is in the past (could have be deleted in Europe and should also be gone in the US). Hi Christian, I don't quite get the above paragraph. If you search for db entries which have been created in the last 3 hours and you have a column "created_on" which stores the time of creation incl. time zone (of your server) you won't face any problems because you can simply search for them. The problem occurs only if you store the current time of the user without time zone in the "created_on" column. To the original question: I'd say that the conversion between time zones belongs in the View. As you are doing it already with [% study.time.convertTZ(c.user) %]. I see that this means you have to type more but neither the controller nor the model should do this conversion. moritz ___ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] User timezones
2009/6/25 Christian Lackas : >> I mean, you're going to have to retrieve each record per user anyway, >> why not retrieve, convert, and stuff it into the per-user session? > > I cannot store all these times in the session, since I have a few > million database entries that all have different timestamps, that should > be converted transparently whenever I need them. I believe he's suggesting that you store the timezone that the user uses in the session. You seem to be confusing (a) the timezone to use in the DB and (b) the timezone that the user is using, and assuming that you should store the date in the DB in the timezone that the user is using. That's what it looks like to me, anyway. I would make use of user's timezone as part of the view/controller layers, and use a fixed timezone (say UTC) for the DB layers. Conversion is a function that your view layer's DateTime formatting function does - in the view, since it's a matter of what the user wants to see, rather than anything about the date data itself - and you similarly need a converter on input to attach a timezone to the DateTimes you create from user-supplied dates. Storing a DateTime with timezone to a UTC- (or otherwise) labelled DBIC DB column will convert the date to the correct timezone before saving it in the database. DateTime knows all about timezones; let it do all the work of converting. -- Ian. ___ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] User timezones
2009/6/25 Moritz Onken : > which stores the time of creation incl. time zone (of your server) A time column typically stores a time without the timezone. If you want to store the timezone you need a second column - otherwise you declare the timezone in the column definition and you can safely assume all times stored are in that timezone. (I think I'm saying what you *meant*, but it's not quite what you *wrote*.) > To the original question: > I'd say that the conversion between time zones belongs in the View. As you > are > doing it already with [% study.time.convertTZ(c.user) %]. I see that this > means you have to type more ... but study.time stringifies the DateTime to a (by default) really ugly date, so you need a formatting call anyway. (Yes, you could specify the format when you define the column, too, but then your model is determining what format your view outputs - that's got issues with separation of responsibility.) -- Ian. ___ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] User timezones
Devin Austin wrote: > you could simply create a column and add the GMT offset. NO! If you only use GMT offsets you'll just annoy your users anywhere in the world that has DST. If that's the only solution don't bother - just use a relevant fixed timezone. Much better to use the Olsen DB timezone names (DateTime supports them). my $dt = DateTime->new( year => 2009, month => 6, day => 25, hour => 15, minute => 42, time_zone => 'Europe/London'); print $dt->datetime, "\n"; $dt->set_time_zone('America/New_York'); print $dt->datetime, "\n"; As far as the original question - you could pass the user's choice of timezone as a parameter when you call the model to request the time. So instead of: $object->creation_date->strftime(' ... '); $object->creation_date($user->prefs->tz)->strftime(' ... '); That still allows you to have a model that will work without being part of a web request and that is easily testable. Carl ___ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] User timezones
* Ian Wells [090625 12:52]: Hi Everybody, first of all, thanks for all your input. > I would make use of user's timezone as part of the view/controller > layers, and use a fixed timezone (say UTC) for the DB layers. OK, as said before, I already had the feeling that it does not fit into the model, however, there it would have been the most convenient. That said, I will now bite the bullet and do it the hard way, but won't have the feeling to make it more complicated than necessary, anymore. Christian -- http://www.inviCRO.com/ ___ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] User timezones
2009/6/29 Christian Lackas : > OK, as said before, I already had the feeling that it does not fit into > the model, however, there it would have been the most convenient. As I say, you'll need a formatting function or functions to turn dates-as-objects into dates in your page, regardless of timezones. You can set up your formatter that that it's initailised withh a timezone, and then your translation from DB-zone to view-zone comes for free as you would have to do the formatting call anyway. So: Once, somewhere once you've discovered the user and know their timezone: my $user=... DateFormatter->output_tz($user->timezone); In your view, and I assume TT here and that you've set up DateFormatter as a plugin or similar: [% DateFormatter.as_datetime(my_row.birthday) %] About as simple as it's ever likely to be, with the added advantage that you have a date formatter with a number of functions to output dates in one of a limited number of formats, so that your app has a consistent appearance. -- Ian. ___ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/