Multi-timezone support in webapplicatie: waar converteren?

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • JayVee
  • Registratie: Mei 2002
  • Laatst online: 31-08 10:22

JayVee

shibby++!

Topicstarter
Onze webapplicatie gaat binnenkort wereldwijd gebruikt worden (*O* :Y) ), en dus ben ik aan het kijken hoe we het beste met verschillende tijdzones kunnen werken. Belangrijk: gebruikers kunnen zelf datums en tijden in hun eigen tijdzone opgeven.

Ik heb er (voorlopig) voor gekozen om alle datetimes in UTC op te slaan in de database. Eigenlijk moet de hele applicatie uit gaan van tijden in UTC. Bij het inlogformulier wordt dmv. javascript de offset van de gebruiker vastgelegd, zodat alle tijden vertaald kunnen worden naar haar zone. Bij het opslaan van door gebruikers gespecificeerde tijden worden deze weer vertaald naar UTC.

De vraag is nu waar precies de conversie moet gebeuren.

Op dit moment hebben we bijvoorbeeld de volgende module:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class SaveResult extends Module {
  // deze functie is een wrapper om de rest van de API
  // aan te roepen vanuit een HTTP request
  public function handleRequest ( Request $r ) {
    $this->storeResult( $r->get('result') ); // alle name="result[$var]" velden van een <form>
  }
  
  // dit is de API die deze module beschikbaar stelt aan de rest van de applicatie.
  // wordt ook gebruikt door importscripts, ander maatwerk, etc
  public function storeResult ( array $result ) {
    $result = $this->sanitizeResult( $result );
    return DB::insert( $result );
  }
  
  public function updateResult ( $id, array $result ) {
    $result = $this->sanitizeResult( $result );
    DB::update( $id, $result );
  }
  
  protected function sanitizeResult ( array $result ) {
    // klopt alles?
    // ==> hier $result['datetime'] vertalen naar UTC <==
  }
  
  public function getResult ( $id ) {
    return DB::get( $id );
  }
}


Het probleem hier is dat de applicatie niet helemaal in UTC werkt: storeResult verwacht tijden in de tijdzone van de gebruiker. getResult haalt ze uit de database als UTC.

Stel een stuk maatwerkcode moet een waarde (bijv. "klaar") van een resultaat aanpassen:
PHP:
1
2
3
4
$sr = new SaveResult();
$result = $sr->getResult( 1337 );
$result['klaar'] = false;
$sr->updateResult( 1337, $result );  // oops, hier wordt de tijd opnieuw geconverteerd!

Callers moeten erop letten dat getResult UTC oplevert, maar [updateResult] verwacht tijden in user timezone. Dit gaat gegarandeerd ergens mis!


Alternatief 1: globaal UTC
Het ligt voor de hand ervoor te zorgen dat het systeem alle tijden als UTC moet beschouwen. SaveResult::storeResult moet dus geen conversie doen, maar dat aan callers overlaten.

Nadeel is dat er dan op erg veel plekken code gedupliceerd moet worden. Daarnaast weet de caller misschien niet waar de datums zitten!

In het voorbeeld hierboven zou handleRequest de conversie (zelf) moeten doen, maar eigenlijk moet deze functie alleen data uit het HTTP Request halen en aan de juiste functie geven (Controller). De functie moet zich niet inhoudelijk ermee bemoeien!


Alternatief 2: globaal user timezone
Tijden worden als UTC opgeslagen, maar direct geconverteerd naar user timezone zodra ze uit de databsae komen.

Vind ik bijzonder lelijk, want de DB moet nu uitzoeken welke velden datetime zijn en conversie doen. Bah bah bah, DB moet zich niet met inhoud bezig houden maar (alleen) de verbinding met de database abstraheren.


Alternatief 3: tijden niet als string, maar objecten rondsturen
Zo heb je in PHP bijvoorbeeld DateTime. Op die manier houd je automatisch bij wat de tijdzone van een bepaalde tijd is.

Combineert de nadelen van vorige twee alternatieven (zie hieronder).


Conclusie
Is er een manier om consistent over de hele codebase om te gaan met datetimes, zonder de verantwoordelijkheid voor conversie te leggen bij stukken code die niet af horen te weten van de inhoud van de data (Module::handleRequest en DB::get)?

[ Voor 0% gewijzigd door JayVee op 26-03-2012 13:58 . Reden: typo ]

ASCII stupid question, get a stupid ANSI!


Acties:
  • 0 Henk 'm!

  • djc
  • Registratie: December 2001
  • Laatst online: 08-09 23:18

djc

Ik zou overal UTC doen en pas ergens in de templating-laag weer converteren naar user-timezone.

Rustacean


Acties:
  • 0 Henk 'm!

  • JayVee
  • Registratie: Mei 2002
  • Laatst online: 31-08 10:22

JayVee

shibby++!

Topicstarter
djc schreef op maandag 26 maart 2012 @ 14:15:
Ik zou overal UTC doen en pas ergens in de templating-laag weer converteren naar user-timezone.
Akkoord, dat is wat ik nu ook doe. Met andere woorden: bij presentatie zo laat mogelijk converteren.

Maar betekend dat aan de andere kant (inkomende data) dat het zo vroeg mogelijk geconverteerd moet worden?

ASCII stupid question, get a stupid ANSI!


Acties:
  • 0 Henk 'm!

  • IceM
  • Registratie: Juni 2003
  • Laatst online: 19:37
Conversie van input (gebruikerstijd naar utc tijd) verwerk je in de controllerlaag lijkt me, niet in de view. Conversie van output (utc tijd naar gebruikerstijd) wel.

...


Acties:
  • 0 Henk 'm!

  • mindcrash
  • Registratie: April 2002
  • Laatst online: 22-11-2019

mindcrash

Rebellious Monkey

IceM schreef op maandag 26 maart 2012 @ 15:09:
Conversie van output (utc tijd naar gebruikerstijd) wel.
Is volgens mij ook niet echt bepaald handig. Waar ikzelf deze code zou stoppen is het punt dat ik domein entiteiten naar presentation models map en deze teruggeef aan de view; ook in de controller dus.

"The people who are crazy enough to think they could change the world, are the ones who do." -- Steve Jobs (1955-2011) , Aaron Swartz (1986-2013)


Acties:
  • 0 Henk 'm!

  • Megamind
  • Registratie: Augustus 2002
  • Laatst online: 10-09 22:45
IceM schreef op maandag 26 maart 2012 @ 15:09:
Conversie van input (gebruikerstijd naar utc tijd) verwerk je in de controllerlaag lijkt me, niet in de view. Conversie van output (utc tijd naar gebruikerstijd) wel.
Inderdaad, zo doe ik het zelf ook met MVC. Tijden moet je eigenlijk altijd UTC opslaan in de database anders krijg je gezeur met wintertijd / zomertijd, dat is gewoon een goede gewoonte.

Acties:
  • 0 Henk 'm!

  • CyBeR
  • Registratie: September 2001
  • Niet online

CyBeR

💩

JayVee schreef op maandag 26 maart 2012 @ 14:49:
[...]

Akkoord, dat is wat ik nu ook doe. Met andere woorden: bij presentatie zo laat mogelijk converteren.

Maar betekend dat aan de andere kant (inkomende data) dat het zo vroeg mogelijk geconverteerd moet worden?
Dat is ook de beste manier.

Zodra ergens een tijd ingevoerd wordt, die omzetten naar UTC en dát opslaan. Daarna bij het weergeven weer omrekenen naar de tijd in de tijdzone die je wilt gebruiken.

All my posts are provided as-is. They come with NO WARRANTY at all.


Acties:
  • 0 Henk 'm!

  • Gerco
  • Registratie: Mei 2000
  • Laatst online: 01-10 16:14

Gerco

Professional Newbie

Megamind schreef op maandag 26 maart 2012 @ 15:14:
[Inderdaad, zo doe ik het zelf ook met MVC. Tijden moet je eigenlijk altijd UTC opslaan in de database anders krijg je gezeur met wintertijd / zomertijd, dat is gewoon een goede gewoonte.
Dat kun je ook niet zomaar doen. Het hangt af van wat de data betekent. Soms verwacht men dat je tijden meegaan met de winter/zomertijd. Als ik een afspraak in mijn agenda heb staan voor 14:00 volgende week maandag en dat is na de zomet/winter tijd overgang verwacht ik wel dat die nog steeds op 14:00 staat wanneer het maandag is en niet op 15:00 of 13:00.

KPN doet dat verkeerd met hun Samsung Digitenne ontvangers, die verplaatsen dus je geprogrammeerde opnames met een uur bij een zomer of wintertijd overgang.

- "Als ik zou willen dat je het begreep, legde ik het wel beter uit!" | All number systems are base 10!


Acties:
  • 0 Henk 'm!

  • Stilgar
  • Registratie: Maart 2002
  • Niet online
JayVee schreef op maandag 26 maart 2012 @ 14:49:
Maar betekend dat aan de andere kant (inkomende data) dat het zo vroeg mogelijk geconverteerd moet worden?
Zoals anderen al schrijven: lijkt me wel. Als je meteen converteert hoef je bij de rest van je code niet meer na te denken of bij te houden of het om een tijd in UTC format gaat, en deze code hoeft zich daar niet meer bewust van te zijn.

Ik zou de invoer zo snel mogelijk converteren naar een DateTime. Alle andere functies kunnen dan eenduidig met deze data omgaan. Dit is ook makkelijker voor validatie, daarvoor moet je vaak ook al weten wat een bepaalde waarde 'betekent'. Je kunt niet controleren of een datum bijvoorbeeld in het verleden ligt tenzij je eerst converteert naar een eenduidig format.

Als dit tot veel gedupliceerde code leidt moet je denk ik gaan nadenken over het aanpassen van het design van je applicatie.
Gerco schreef op maandag 26 maart 2012 @ 15:23:
Dat kun je ook niet zomaar doen. Het hangt af van wat de data betekent. Soms verwacht men dat je tijden meegaan met de winter/zomertijd. Als ik een afspraak in mijn agenda heb staan voor 14:00 volgende week maandag en dat is na de zomet/winter tijd overgang verwacht ik wel dat die nog steeds op 14:00 staat wanneer het maandag is en niet op 15:00 of 13:00.
Dit vang je al af wanneer je de invoer van de gebruiker (26 maart 2012 14:00) converteert naar UTC, daarbij houdt je gewoon rekening met DST (daylight saving time).

[ Voor 24% gewijzigd door Stilgar op 26-03-2012 15:30 ]


Acties:
  • 0 Henk 'm!

  • CyBeR
  • Registratie: September 2001
  • Niet online

CyBeR

💩

Gerco schreef op maandag 26 maart 2012 @ 15:23:
[...]

Dat kun je ook niet zomaar doen. Het hangt af van wat de data betekent. Soms verwacht men dat je tijden meegaan met de winter/zomertijd. Als ik een afspraak in mijn agenda heb staan voor 14:00 volgende week maandag en dat is na de zomet/winter tijd overgang verwacht ik wel dat die nog steeds op 14:00 staat wanneer het maandag is en niet op 15:00 of 13:00.

KPN doet dat verkeerd met hun Samsung Digitenne ontvangers, die verplaatsen dus je geprogrammeerde opnames met een uur bij een zomer of wintertijd overgang.
Dan doe jij (en dan doen zij) de conversie fout. Bij het converteren van een lokale datum/tijd naar UTC moet je direct rekening houden met zulke zaken als zomer/wintertijd. Daar is de tz database voor, om te zorgen dat je dat goed kunt doen.

Eerlijkheid gebiedt te zeggen dat wij hier ook al eens ingetrapt zijn, doordat op twee plekken verschillende ideeën over die conversie gehanteerd werden. Dat ging goed voor recente data, maar het ging om een website met daarin geboorte- en sterfdata van Joden die tijdens de tweede wereldoorlog omgekomen zijn, en toen had men andere ideeën over zomer/wintertijd en dergelijke.

All my posts are provided as-is. They come with NO WARRANTY at all.


Acties:
  • 0 Henk 'm!

  • leuk_he
  • Registratie: Augustus 2000
  • Laatst online: 15-07 15:35

leuk_he

1. Controleer de kabel!

Gerco schreef op maandag 26 maart 2012 @ 15:23:
Dat kun je ook niet zomaar doen. Het hangt af van wat de data betekent. Soms verwacht men dat je tijden meegaan met de winter/zomertijd. Als ik een afspraak in mijn agenda heb staan voor 14:00 volgende week maandag en dat is na de zomet/winter tijd overgang verwacht ik wel dat die nog steeds op 14:00 staat wanneer het maandag is en niet op 15:00 of 13:00.
Als je goed omrekent, dan weet de invoer procedure dat op die betreffende datum al zomer/wintertijd is en houd dus rekening met de datum voor het omrekenen van de tijd. maar idd een goede testcase.

En bedenk dat je datums (zonder tijd) niet gaat omrekenen. het verschil van een date en een date-time veld is belangrijk.

En verschillen rond zomer winter tijd zijn ook belangrijk. Heb hier een major wtf moment gehad dat iemand niet kon worden ingedeeld. Tja, CAO geeft 2 dagen -> 48 rusttijd aan, en afgelopen weekend was maar 47 uur...

Need more data. We want your specs. Ik ben ook maar dom. anders: forum, ff reggen, ff topic maken
En als je een oplossing hebt gevonden laat het ook ujb ff in dit topic horen.


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01-10 23:36

.oisyn

Moderator Devschuur®

Demotivational Speaker

JayVee schreef op maandag 26 maart 2012 @ 13:01:
Alternatief 3: tijden niet als string, maar objecten rondsturen
Zo heb je in PHP bijvoorbeeld DateTime. Op die manier houd je automatisch bij wat de tijdzone van een bepaalde tijd is.
Dit is sowieso aan te raden, nog los van je hele probleem. Een tijdstip is een tijdstip, ongeacht de locale waarin hij gerepresenteerd wordt. Door daar het juiste object bij te gebruiken zorg je ervoor dat er nooit verwarring kan ontstaan.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Gerco
  • Registratie: Mei 2000
  • Laatst online: 01-10 16:14

Gerco

Professional Newbie

leuk_he schreef op maandag 26 maart 2012 @ 15:33:
Als je goed omrekent, dan weet de invoer procedure dat op die betreffende datum al zomer/wintertijd is en houd dus rekening met de datum voor het omrekenen van de tijd. maar idd een goede testcase.
Het probleem met de digitenne apparatuur was met herhalende opnames. Elke dag om 19:00 verschuift automatisch naar elke dag om 20:00 of 18:00, afhankelijk van de richting van de tijd overgang.

Sommige dingen wil je in UTC opslaan en sommige dingen wil je als lokale tijdstippen opslaan. Hangt van de soort data af. Blindelings alle tijden en datums naar UTC converteren lijkt een goed idee, maar is het niet wat mij betreft. Je moet goed kijken welke velden welk soort data representeren.

- "Als ik zou willen dat je het begreep, legde ik het wel beter uit!" | All number systems are base 10!


Acties:
  • 0 Henk 'm!

  • JayVee
  • Registratie: Mei 2002
  • Laatst online: 31-08 10:22

JayVee

shibby++!

Topicstarter
Consensus tot zover is "zo vroeg mogelijk converteren".

Op die manier heb je over het hele systeem (afgezien van die eerste stap dus) dezelfde timezone, wat lekker consistent is.

Bij een API als
PHP:
1
2
3
class MyAPI {
  public function do ( $date, $somethingElse ) {}
}

Vind ik het ook een goede zaak om de caller de conversie te laten doen.

In mijn geval zit de datum echter een beetje verstopt: het is een van vele waarden. De controller (handleRequest) kan al deze waarden nu uit het Request halen en doorgeven naar de API, zonder meer te hoeven af te weten van de inhoud, en de eisen van de API:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
class Form {
  // lijst van velden, met verschillende types (datum, keuze, check, etc)
  protected $elements;
}

class Module {
  public abstract function handleRequest ( Request $r );
}

class ShowForm extends Module {
  public function handleRequest ( Request $r ) {
    $this->presentForm(
      new Form( (int)$r->get('formid') )
    );
  }

  public function presentForm ( Form $form ) {
    // echo '<form>' op basis van definitie van $form,
    // met name="data[]" voor de gedefinieerde velden
  }
}

class SaveForm extends Module {
  public function handleRequest( Request $r ) {
    // !! Deze functie zou dus meer moeten "weten" dan de eigen API,
    // maar dus ook afweten van Form en datumvelden en timezones !!
    $this->save(
      new Form( (int)$r->get('formid') )
      $r->get( 'data' )
    );
  }
  
  public function save ( Form $form, array $data ) {
    // $form beschrijft $data: voor elk $form->elements is er een key in $data
    // $data bevat o.a. een (of meerdere) datum
  }
}


In dit geval vind ik het minder netjes om de Controller (handleRequest) verantwoordelijk te maken voor de conversie, want deze moet nu afweten van Form en timezone en zo.

Ik neig echter dit aan te passen zoals wordt voorgesteld, vooral om consistentie te krijgen.

offtopic:
Leuk dat weer er zo snel zo een goede discussie op gang komt! _/-\o_

ASCII stupid question, get a stupid ANSI!


Acties:
  • 0 Henk 'm!

  • Megamind
  • Registratie: Augustus 2002
  • Laatst online: 10-09 22:45
Gerco schreef op maandag 26 maart 2012 @ 16:15:
[...]
Sommige dingen wil je in UTC opslaan en sommige dingen wil je als lokale tijdstippen opslaan. Hangt van de soort data af. Blindelings alle tijden en datums naar UTC converteren lijkt een goed idee, maar is het niet wat mij betreft. Je moet goed kijken welke velden welk soort data representeren.
Daarom moet je het goed converteren, dan heb je er ook geen last van. Een afspraak om 1 uur 's middags is juist met de winter/zomertijd wissel ook om 1 uur 's middags, anders zou deze een uur verspringen.

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01-10 23:36

.oisyn

Moderator Devschuur®

Demotivational Speaker

Gerco schreef op maandag 26 maart 2012 @ 16:15:
[...]

Het probleem met de digitenne apparatuur was met herhalende opnames. Elke dag om 19:00 verschuift automatisch naar elke dag om 20:00 of 18:00, afhankelijk van de richting van de tijd overgang.

Sommige dingen wil je in UTC opslaan en sommige dingen wil je als lokale tijdstippen opslaan. Hangt van de soort data af. Blindelings alle tijden en datums naar UTC converteren lijkt een goed idee, maar is het niet wat mij betreft. Je moet goed kijken welke velden welk soort data representeren.
Maar dat zijn dan ook geen datums, en dus valt er ook weinig te corrigeren.

[ Voor 3% gewijzigd door .oisyn op 26-03-2012 16:22 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • JayVee
  • Registratie: Mei 2002
  • Laatst online: 31-08 10:22

JayVee

shibby++!

Topicstarter
Megamind schreef op maandag 26 maart 2012 @ 16:16:
[...]
Daarom moet je het goed converteren, dan heb je er ook geen last van. Een afspraak om 1 uur 's middags is juist met de winter/zomertijd wissel ook om 1 uur 's middags, anders zou deze een uur verspringen.
offtopic:
Gisterochtend bleef een machine aan staan die 's ochtends om 2:00 wakker wordt en (volgens cron job) om 2:05 een backup binnen slurpt en weer gaat slapen.

Gisteren ging het niet goed omdat 2:05 niet bestond... :+

ASCII stupid question, get a stupid ANSI!


Acties:
  • 0 Henk 'm!

  • ytterx
  • Registratie: Januari 2009
  • Laatst online: 02-10 17:23
Mogelijk een beetje offtopic, maar javascript kan ik uitzetten.. daar al aangedacht?? Dan zijn de datums die je binnen krijgt zoizo invalid.

*bijdehante LMGTFY linkjes zijn niet gewenst. >> [google="php client timezone"] werkt net zo goed

Mogelijk helpt je dat ook iets.

[ Voor 27% gewijzigd door RobIII op 26-03-2012 16:41 ]


Acties:
  • 0 Henk 'm!

  • leuk_he
  • Registratie: Augustus 2000
  • Laatst online: 15-07 15:35

leuk_he

1. Controleer de kabel!

ytterx schreef op maandag 26 maart 2012 @ 16:35:
Mogelijk een beetje offtopic, maar javascript kan ik uitzetten
En staat bij mobiele browsers soms ook uit..

Bij presentatielaag dacht ik ook niet aan javascript in browser, maar laatste php laag. maar TS heeft het idd over javascript.

Need more data. We want your specs. Ik ben ook maar dom. anders: forum, ff reggen, ff topic maken
En als je een oplossing hebt gevonden laat het ook ujb ff in dit topic horen.


Acties:
  • 0 Henk 'm!

  • Stilgar
  • Registratie: Maart 2002
  • Niet online
JayVee schreef op maandag 26 maart 2012 @ 16:16:
In dit geval vind ik het minder netjes om de Controller (handleRequest) verantwoordelijk te maken voor de conversie, want deze moet nu afweten van Form en timezone en zo.
Als ik het goed zie weet handleRequest al van Form. Aangezien Form waarschijnlijk op de hoogte is van de verschillende datatypen van de elementen, kan (een methode van) Form de conversie doen en evt. een geconverteerde set elementen teruggeven.

Acties:
  • 0 Henk 'm!

  • Cartman!
  • Registratie: April 2000
  • Niet online
Ik zou denken zoiets:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
date_default_timezone_set('UTC');

// invoer in NL tijdzone
$created = new DateTime('2012-03-26 17:00:00', new DateTimeZone('Europe/Amsterdam'));

// opslaan als UTC tijdzonde
$created->setTimezone(new DateTimeZone('UTC')); // wordt 2012-03-26 15:00:00

// tonen waarde uit db
$created = new DateTime('2012-03-26 15:00:00');

// omzetten naar NL timezone
$created->setTimezone(new DateTimeZone('Europe/Amsterdam'));
echo $created; // 2012-03-26 17:00:00

Correct me if I'm wrong maar dit lijkt netjes rekening te houden met DST vanuit zichzelf.

[ Voor 3% gewijzigd door Cartman! op 26-03-2012 17:06 ]


Acties:
  • 0 Henk 'm!

  • cariolive23
  • Registratie: Januari 2007
  • Laatst online: 18-10-2024
Ik zou het in de database (PostgreSQL) oplossen, daar kun je ook eenvoudig per gebruiker de tijdzone laten vastleggen, dat kunnen ze zelf onderhouden. PostgreSQL kent het datatype TIMESTAMP WITH TIME ZONE, werkt perfect voor dit soort zaken:

SQL:
1
2
3
4
5
6
7
8
9
10
CREATE TABLE users(name text, tz text);
INSERT INTO users(name, tz) VALUES('John', 'America/New_York');
INSERT INTO users(name, tz) VALUES('Eric', 'Europe/Amsterdam');
INSERT INTO users(name, tz) VALUES('Kay', 'America/Los_Angeles');

SELECT 
    name,
    NOW() AT TIME ZONE tz
FROM
    users;

Resultaat:
John,2012-03-26 14:45:30.857931
Eric,2012-03-26 20:45:30.857931
Kay,2012-03-26 11:45:30.857931

Je kunt ook met UTC e.d. werken, net wat jij handig vindt.

Acties:
  • 0 Henk 'm!

  • curvemod
  • Registratie: Maart 2009
  • Laatst online: 22-09 09:15
Eens met Cartman!, dit lijkt me ook de netste oplossing om gebruik te maken van de standaard DateTime class, denk dat die class in de toekomst veel voordelen biedt met date operaties (tijd toevoegen, conversies, etc). ;)

Acties:
  • 0 Henk 'm!

  • JayVee
  • Registratie: Mei 2002
  • Laatst online: 31-08 10:22

JayVee

shibby++!

Topicstarter
ytterx schreef op maandag 26 maart 2012 @ 16:35:
Mogelijk een beetje offtopic, maar javascript kan ik uitzetten.. daar al aangedacht?? Dan zijn de datums die je binnen krijgt zoizo invalid.
Zonder javascript kun je niet inloggen op onze applicatie. We vereisen het gewoon, punt uit. :+ (Het is een interne bedrijfsapplicatie, ook al wordt het als SaaS aangeboden. Het toegankelijk maken voor browsers zonder javascript vinden we gewoon niet de extra moeite waard.)
Cartman! schreef op maandag 26 maart 2012 @ 17:05:
Ik zou denken zoiets:
...
Correct me if I'm wrong maar dit lijkt netjes rekening te houden met DST vanuit zichzelf.
Hoe je tijden kunt converteren is het probleem niet (dat heb ik al uitgezocht). Het gaat mij om de vraag waar (in welke laag van de applicatie) moet je de conversie doen?

Trouwens: ik had het eerst precies zo geïmplementeerd als jij hier laat zien. Echter, aangezien gebruikers niet per se vaste tijdzones hebben (denk aan managers of verkopers die vanuit overal in kunnen loggen) heb ik ervoor gekozen om bij het inloggen de offset ten opzichte van UTC (js: new Date().getTimezoneOffset()) in de session op te slaan. Ik werk dus niet met timezones, maar met een UTC offset.
PHP:
1
2
3
4
5
6
7
8
class DateUtils {
  public static function dateInUserTZ ( $format = 'Y-m-d H:i:s' ) {
    return date(
      $format,
      time() + ( 60 * User::getInstance()->timeZoneOffset )
    );
  }
}
Stilgar schreef op maandag 26 maart 2012 @ 16:53:
[...]
Als ik het goed zie weet handleRequest al van Form. Aangezien Form waarschijnlijk op de hoogte is van de verschillende datatypen van de elementen, kan (een methode van) Form de conversie doen en evt. een geconverteerde set elementen teruggeven.
Ja, dat is inderdaad een goed idee. Op die manier ligt de kennis van dit probleem bij Form en niet bij handleRequest.

Helaas is date de enige uitzondering, dus ga ik Form::convertData() optuigen voor (op dit moment) een enkele regel code. Qua design lijkt mij dat echter de juiste weg.

ASCII stupid question, get a stupid ANSI!


Acties:
  • 0 Henk 'm!

  • Cartman!
  • Registratie: April 2000
  • Niet online
JayVee schreef op dinsdag 27 maart 2012 @ 11:37:
Hoe je tijden kunt converteren is het probleem niet (dat heb ik al uitgezocht). Het gaat mij om de vraag waar (in welke laag van de applicatie) moet je de conversie doen?
In je presentatielaag dus, heb je die niet? Ik zou simpelweg een helper voor me zien die een timezone danwel offset accepteert.

PHP:
1
2
$dateTime = new DateTime('2012-03-27 14:30:00');
$dateTime->add(new DateInterval('PT' . $offset . 'H'))->format('Y-m-d H:i:s');


Ik werk liever met DateTime-objecten dan met integers maar wellicht is dat persoonlijke voorkeur.

(bij een negatieve offset moet je natuurlijk 'sub' gebruiken ipv. 'add' :) )

[ Voor 5% gewijzigd door Cartman! op 27-03-2012 14:56 ]


Acties:
  • 0 Henk 'm!

  • JayVee
  • Registratie: Mei 2002
  • Laatst online: 31-08 10:22

JayVee

shibby++!

Topicstarter
Cartman! schreef op dinsdag 27 maart 2012 @ 14:32:
[...]
In je presentatielaag dus, heb je die niet?
Ik zou simpelweg een helper voor me zien die een timezone danwel offset accepteert.
Bij het tonen van tijden uiteraard de presentatielaag, maar bij verwerken? De helper is het probleem niet.
PHP:
1
2
$dateTime = new DateTime('2012-03-27 14:30:00');
$dateTime->add(new DateInterval('PT' . $offset . 'H'))->format('Y-m-d H:i:s');

Ik werk liever met DateTime-objecten dan met integers maar wellicht is dat persoonlijke voorkeur.

(bij een negatieve offset moet je natuurlijk 'sub' gebruiken ipv. 'add' :) )
Dat DateInterval-formaat is vreselijk! Aangezien sommige landen halve uren verschillen van UTC (bijv. India 4,5) wil je in minuten werken. Maar voor dit formaat moet je uren en minuten apart opgeven, waarbij je 60 minuten als 1 uur moet opgeven.

Uiteraard allemaal op te lossen met modulo etc, maar dan vind ik time() + $offset toch vele malen lekkerder en duidelijker werken!

Plus het feit (zoals boven uitgelegd) dat een timezone-instelling minder flexibel is dan een "offset bij login". Bij de eerste moet je per gebruiker extra data vastleggen en instelbaar maken. Bij de tweede opzet hoeft dat niet, en neemt het systeem (bij elke login) de tijd van het OS over (via de browser).

ASCII stupid question, get a stupid ANSI!


Acties:
  • 0 Henk 'm!

  • Cartman!
  • Registratie: April 2000
  • Niet online
JayVee schreef op dinsdag 27 maart 2012 @ 16:38:
[...]
Bij het tonen van tijden uiteraard de presentatielaag, maar bij verwerken? De helper is het probleem niet.
Er komt een datum binnen, de offset heb je dus die verreken je precies zoals als bij de uitvoer.
Dat DateInterval-formaat is vreselijk! Aangezien sommige landen halve uren verschillen van UTC (bijv. India 4,5) wil je in minuten werken. Maar voor dit formaat moet je uren en minuten apart opgeven, waarbij je 60 minuten als 1 uur moet opgeven.

Uiteraard allemaal op te lossen met modulo etc, maar dan vind ik time() + $offset toch vele malen lekkerder en duidelijker werken!
Je kan gewoon het aantal in minuten opgeven hoor, dus bijv. 270 minuten (PT270M) voor 4,5 uur. Maar zoals ik zei, het is persoonlijke voorkeur....ik werk graag met DateTime.
Plus het feit (zoals boven uitgelegd) dat een timezone-instelling minder flexibel is dan een "offset bij login". Bij de eerste moet je per gebruiker extra data vastleggen en instelbaar maken. Bij de tweede opzet hoeft dat niet, en neemt het systeem (bij elke login) de tijd van het OS over (via de browser).
Overigens vind ik het ophalen van de huidige offset via JS een leuke methode die ik zeker zal onthouden voor als ik hetzelfde probleem tegenkom. Als ik een user normaal zou laten registreren zou ik de persoon een timezone laten kiezen, mits ik er vanuit mag gaan dat een user binnen die tijdzone blijft natuurlijk.

Acties:
  • 0 Henk 'm!

  • Erkens
  • Registratie: December 2001
  • Niet online

Erkens

Fotograaf

Het ligt er natuurlijk ook aan waarvoor de tijden gebruikt worden. Als het om afspraken gaat is het juist wel handig om ook de gebruikte tijdzone te onthouden. Erg jammer is het dan ook dat javascript alleen een offset heeft ten opzichte van UTC en niet de werkelijke timezone informatie.

Acties:
  • 0 Henk 'm!

  • Cartman!
  • Registratie: April 2000
  • Niet online
Die tijdzone heeft hij niet, dat is het probleem imo. Ik reken liever in tijdzones dan in offsets omdat je met een offset niet terug kunt rekenen naar een specifieke tijdzone. Had leuk geweest als JS dit had kunnen vertellen idd.

Acties:
  • 0 Henk 'm!

  • Erkens
  • Registratie: December 2001
  • Niet online

Erkens

Fotograaf

Cartman! schreef op dinsdag 27 maart 2012 @ 17:13:
Die tijdzone heeft hij niet, dat is het probleem imo. Ik reken liever in tijdzones dan in offsets omdat je met een offset niet terug kunt rekenen naar een specifieke tijdzone. Had leuk geweest als JS dit had kunnen vertellen idd.
Gewoon de gebruikte tijdzone aan de gebruiker vragen, en daarbij heb je zelfs nog diverse opties:

- altijd vragen bij inloggen
- globale setting (eventueel "eenmalig" te overrulen bij inloggen)
- tijdzone "gokken" adhv de offset van javascript en IP informatie

Die laatste is erg tricky want je kan die info nergens op vastpinnen, echter in het geval van JayVee kan het wellicht wat beter aangezien het om een interne applicatie gaat waardoor je wellicht meer info kan vergaren.

Acties:
  • 0 Henk 'm!

  • Cartman!
  • Registratie: April 2000
  • Niet online
Vragen bij inloggen vind ik ook netter maar dat lijkt de TS niet te willen omdat het automatisch moet (begrijp ik althans).

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01-10 23:36

.oisyn

Moderator Devschuur®

Demotivational Speaker

JayVee schreef op dinsdag 27 maart 2012 @ 16:38:
Plus het feit (zoals boven uitgelegd) dat een timezone-instelling minder flexibel is dan een "offset bij login". Bij de eerste moet je per gebruiker extra data vastleggen en instelbaar maken. Bij de tweede opzet hoeft dat niet, en neemt het systeem (bij elke login) de tijd van het OS over (via de browser).
En wat als een gebruiker nou op zondag 25 maart 1:00 inlogt en z'n sessie duurt 2 uur?

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • JayVee
  • Registratie: Mei 2002
  • Laatst online: 31-08 10:22

JayVee

shibby++!

Topicstarter
Cartman! schreef op dinsdag 27 maart 2012 @ 16:51:
[...]
Er komt een datum binnen, de offset heb je dus die verreken je precies zoals als bij de uitvoer.
[...]
Sorry hoor, maar duh! }:O

Nogmaals: het gaat mij om de plek in de applicatie waar dit moet gebeuren.
Je kan gewoon het aantal in minuten opgeven hoor, dus bijv. 270 minuten (PT270M) voor 4,5 uur.
[...]
Dat klopt dus niet:
But the values in this format can not exceed a given period's roll-over-point (e.g. 25 hours is invalid)
Afbeeldingslocatie: http://www.familyrightsassociation.com/ofr/scribbles/by_what_authority/respect_authoritah.jpg
:o


.oisyn schreef op woensdag 28 maart 2012 @ 09:08:
[...]
En wat als een gebruiker nou op zondag 25 maart 1:00 inlogt en z'n sessie duurt 2 uur?
Dan kloppen de tijden na de overgang van 2:00 naar 3:00 uur niet. Twee keer per jaar vette pech >:)
Het is niet voor niets dat de overgang zondag nacht gebeurd lijkt mij. Dit is gewoon een vette won't fix. Niet omdat werken met offset het onmogelijk maakt om dit te fixen, maar omdat ik het niet de moeite waard vind.
Cartman! schreef op dinsdag 27 maart 2012 @ 17:13:
Die tijdzone heeft hij niet, dat is het probleem imo. Ik reken liever in tijdzones dan in offsets omdat je met een offset niet terug kunt rekenen naar een specifieke tijdzone. Had leuk geweest als JS dit had kunnen vertellen idd.
Dat is inderdaad het probleem.

Je kunt de gebruiker er natuurlijk om vragen, en het instelbaar maken (sommige gebruikers loggen vanuit meerdere timezones in!). Werken met de offset gaat automatisch, zonder dat de gebruiker iets van merkt, en heeft daarom mijn voorkeur voor deze applicatie.

[ Voor 6% gewijzigd door JayVee op 28-03-2012 09:31 ]

ASCII stupid question, get a stupid ANSI!


Acties:
  • 0 Henk 'm!

  • Cartman!
  • Registratie: April 2000
  • Niet online
JayVee schreef op woensdag 28 maart 2012 @ 09:24:
[...]

Sorry hoor, maar duh! }:O

Nogmaals: het gaat mij om de plek in de applicatie waar dit moet gebeuren.
Succes, zoek het dan maar uit :Z Volgens mij is er al meerdere keren gezegd waar je dit het best kunt doen, je moet het dan alleen nog ff toepassen op jouw applicatie.
Heb je het geprobeerd? Blijkbaar niet, ik wel.

Acties:
  • 0 Henk 'm!

  • Stilgar
  • Registratie: Maart 2002
  • Niet online
JayVee schreef op woensdag 28 maart 2012 @ 09:24:

Dat klopt dus niet:

"But the values in this format can not exceed a given period's roll-over-point (e.g. 25 hours is invalid)"
De hele quote is:
The specification can also be represented as a date time. A sample of one year and four days would be P0001-00-04T00:00:00. But the values in this format can not exceed a given period's roll-over-point (e.g. 25 hours is invalid).
Als je dit goed leest geldt deze restrictie wanneer je een volledige date time opgeeft (bijv. P0001-00-04T00:00:00). Als je alleen minuten opgeeft zoals Cartman! suggereert gaat het dus goed.

Acties:
  • 0 Henk 'm!

  • Erkens
  • Registratie: December 2001
  • Niet online

Erkens

Fotograaf

JayVee schreef op woensdag 28 maart 2012 @ 09:24:
Je kunt de gebruiker er natuurlijk om vragen, en het instelbaar maken (sommige gebruikers loggen vanuit meerdere timezones in!). Werken met de offset gaat automatisch, zonder dat de gebruiker iets van merkt, en heeft daarom mijn voorkeur voor deze applicatie.
Nadeel is alleen als persoon x een afspaak heeft op 9 uur in Londen, en dus 10 uur in zijn agenda heeft gezet, dan even snel op het vliegveld kijkt en ziet dat het 9 uur is en in zijn hoofd telt hij er een uur bij en is hij dus te laat... Als je de tijdzone het probleem van de gebruiker maakt (dus instelbaar) dan heeft hij overal ter wereld het precies zoals hij het wilt hebben.

Acties:
  • 0 Henk 'm!

  • JayVee
  • Registratie: Mei 2002
  • Laatst online: 31-08 10:22

JayVee

shibby++!

Topicstarter
Cartman! schreef op woensdag 28 maart 2012 @ 12:07:
[...]
Succes, zoek het dan maar uit :Z Volgens mij is er al meerdere keren gezegd waar je dit het best kunt doen, je moet het dan alleen nog ff toepassen op jouw applicatie.
Mijn excuses, ik was een beetje bot. Ik had het idee dat je niet goed had gekeken wat mijn probleem was. Hoe je een datetime converteert is mij duidelijk (en blijkt uit mijn posts denk ik).

Er is inderdaad al verteld waar het moet gebeuren, vandaar dat ik jouw reactie over hoe overbodig vond.
[...]
Heb je het geprobeerd? Blijkbaar niet, ik wel.
O-) Ik dacht van wel (een tijd geleden). Blijkbaar heb ik het toen niet goed genoeg bekeken, want het werkt inderdaad zoals je zegt.

At first I wuz like
Afbeeldingslocatie: http://www.loleg.com/blog/wp-content/uploads/2012/03/id-know-it-if-i-was-wrong.jpg
But now I'm totally like
Afbeeldingslocatie: http://cuteoverload.files.wordpress.com/2009/08/sorry.jpg

ASCII stupid question, get a stupid ANSI!

Pagina: 1