Avatar billede alex15 Nybegynder
29. januar 2010 - 19:50 Der er 24 kommentarer og
1 løsning

International hjemmeside og database - tidsforskelle

Hej allesammen,

Er i gang med at lave en international hjemmeside, hvor jeg skal lave et stort booking system.

Hvordan klarer man problemstillingen mht. tidsforskellene i de forskellige tidszoner?

Normalt henter jeg tiden på følgende måde:

$nutid = date("Y-m-d H:i:s");

Men da dette vil være serverens tidspunkt, ville dette være forkert, hvis personen befandt sig i fx. london?

Håber at i forstår min problem stilling?

Alex
Avatar billede arne_v Ekspert
29. januar 2010 - 19:59 #1
Du gemmer tid i UTC og formaterer efter brugerens praeferancer.

Du kan f.eks. default vise det i GMT og saa lade brugeren selv skifte tidszone til GMT+0100 eller whatever.
Avatar billede alex15 Nybegynder
29. januar 2010 - 22:28 #2
Okay, så jeg skal altså vælge 'timestamp' -> 'CURRENT_TIMESTAMP'? - eller er det indenunder 'Attributter' at jeg skal stille den til noget for at gemme tiden i UTC?

Hvordan gør man det, sorry, har aldrig arbejdet med sådan noget før?

Kunne jeg få dig til at give mig et kort eksempel?

Kan man ikke på en eller anden måde læse hvilken tidszone som brugeren befinder sig i, så han ikke manuelt skal skrifte rundt på dette?
Avatar billede arne_v Ekspert
30. januar 2010 - 20:55 #3
TIMESTAMP gemmes altid internt i UTC.

Du kan prøve at bestemme tidszone udfra IP adresse, men det er ikke specielt pålideligt, fordi brugere som sidder på et firma netværk har ekstern IP hvor firmaets net går ud på internet.
Avatar billede alex15 Nybegynder
30. januar 2010 - 21:12 #4
Okay, så hvad kunne man så gøre? Der må da være en helt standart løsning på dette problem tænker jeg bare?

Men hvis man nu gemmer tiden i TIMESTAMP, hvordan hvordan laver man så tiden om til UK tid?

Hvilken kode skal der bruges til dette?
Avatar billede arne_v Ekspert
31. januar 2010 - 02:29 #5
Hvis du er på nyere PHP kan du bruge DateTime klassen.

Den har en setTimezone metode og en format metode - sæt timezone til det du ønsker inden du formaterer.
Avatar billede alex15 Nybegynder
31. januar 2010 - 12:38 #6
Jeg har følgende PHP version på serveren:
PHP/5.2.3-1ubuntu6.4

Er denne version ny nok?

Hvordan vil du have mig til at sætte timezone inden jeg formaterer.

Har prøvet at læse lidt om det der setTimezone, men synes det virker meget forvirrende?

Jeg kunne ikke overtale dig til at give mig et eksempel vel, om hvordan du ville gøre det?
Avatar billede arne_v Ekspert
31. januar 2010 - 19:06 #7
De spændende ting i DateTime krævet 5.3.

Eksempel:

<?php
date_default_timezone_set('UTC');
$t = time();
echo "Timestamp = $t\r\n";
$dt = new DateTime();
$dt->setTimestamp($t);
$dt->setTimezone(new DateTimeZone('MET'));
$s = $dt->format('Y-m-d H:i:s');
echo "København: $s\r\n";
$dt->setTimezone(new DateTimeZone('GMT'));
$s = $dt->format('Y-m-d H:i:s');
echo "London: $s\r\n"
?>

outputter:

Timestamp = 1264961127
København: 2010-01-31 19:05:27
London: 2010-01-31 18:05:27

Du bør kunne lave noget tilsvarende med PHP 5.2, men det vil kræve lidt mere kode.
Avatar billede alex15 Nybegynder
31. januar 2010 - 19:55 #8
Kunne overveje at få min udbyder til at opdaterer mit PHP på serveren til den nyere version. Kan vel aldrig skade? - Har en dedikeret server stående hos Danhost nemlig.

Okay, men dit eksempel kræver så at man ved om brugeren befinder sig i London, Kbh eller NY? (MET, GMT eller XXX) right?

Hvis jeg så fx. ønsker at oprette en nyhed, eller et arrangement, hvor man typisk gemmer datoen samt tidspunktet for nyheden eller arrangementet.

Hvordan bør jeg så gøre dette? Skal tidspunktet for arrangementet, så gemmes normalt ned på serveren som jeg altid har gjort. Og så når jeg viser nyheden, så omformer man tiden så det svare til den tidszone som bruger befindes sig i?

Håber at du forstår hvad jeg mener? :-)
Avatar billede arne_v Ekspert
31. januar 2010 - 21:10 #9
Som jeg beskerv i et af de tidligere indlæg drejer min kode sig om at vise UTC tid i en ag brugeren valgt tidszone.

For arrangementer ville jeg konsekvent angive lokal tid der hvor arrangementet finder sted.

For nyheder tror jeg at sitets tid er godt nok.
Avatar billede alex15 Nybegynder
31. januar 2010 - 23:02 #10
"... drejer min kode sig om at vise UTC tid i en ag brugeren valgt tidszone." - Det vil altså sige at brugeren selv skal vælge hvilken tidszone han befinder sig i eller hvad?

Hvis man nu tager er konkret problem fra min side:

Serveren står i DK, og en bruger ønsker at logge sig ind fra hans computer i London.

Han taster sin kode forkert ind 5 gange, og dette registeret for hvert forsøg i databasen på følgende måde:

mysql_query("INSERT INTO `login` (`id`) values ('$ip')");

I tabellen 'login' er der et felt som hedder 'date', som er af datatypen 'timestamp', hvor standardværdien er sat til 'CURRENT_TIMESTAMP'. - Derfor udfyldes denne automatisk.

Bruger bliver så blokeret én time fra siden, og jeg ønsker nu at give ham besked om hvornår han kan få adgang igen.

---

$tid = strtotime($row['date']);
$tillaeg = (60 * 60 * 1);
$femtesidsteforsog = date("Y-m-d H:i:s", $tid + $tillaeg);

---

Værdien fra $femtesidsteforsog viser det som den skal i Danmark, men for en bruger der sidder i London, vil værdien bliver 1 time ekstra?

Det vil altså se ud som om at brugeren er blokeret fra siden i 2 timer, og ikke 1 time?

Hvordan ville du løse dette problem?

PS. Du skal vide at jeg sætter utrolig stor pris på din hjælp.
Avatar billede arne_v Ekspert
01. februar 2010 - 02:05 #11
Den pragmatiske løsning:
  brug date("Y-m-d H:i:s P", $tid + $tillaeg)
  og så kan han selv omregne til den tidszone han er i

Den avancerede løsning:
  lad ham vælge tidszone og formater efter denne (nemt i 5.3+)

Den problematiske løsning:
  bestem hans tidszone udfra IP adressen

(det sidste er problematisk hvis han sidder i London men arbejder for et firma med hovedkontor og internet forbindelse i Los Angeles)
Avatar billede alex15 Nybegynder
01. februar 2010 - 12:12 #12
Ud fra det som du siger, så virker det jo til at den avancerede løsning er den bedste så.

Men de må have samme problemstilling i virksomheder som Facebook mv? - Og mener da aldrig at jeg har skulle vælge en tidszone derinde, eller noget? - De benytter sig så af den problematiske løsning så?

---

Mener faktisk aldrig at jeg har selv har skulle vælge hvilken tidszone jeg befinder mig i, når jeg har klikket mig ind på en side?

---

Men hvis jeg lader ham vælge den tidszone som han befinder sig i.

Så skal jeg bruge denne her $femtesidsteforsog, og kører den igennem:

$dt->setTimezone(new DateTimeZone('MET'));
$s = $dt->format('Y-m-d H:i:s');
echo "København: $s\r\n";

Eller hvad?
Avatar billede arne_v Ekspert
01. februar 2010 - 13:47 #13
Hvis man under bruger registreringne skal angive land og by, saa kan tidszonen bestemmes paalideligt.
Avatar billede arne_v Ekspert
01. februar 2010 - 13:48 #14
Bortset fra at i den kode snippet skal 'MET' laves til en variabel.
Avatar billede alex15 Nybegynder
01. februar 2010 - 14:42 #15
Okay, det lyder som den bedste løsning.

Så smider jeg bare placeringen af dem (MET, GMT osv.)  ned i en SESSION['x'] variabel.

Men nu skal jeg lige forstå det korrekt.

Så alt input til databasen, fra nyheder, kalender mv. skal blot foregå på samme måde som jeg normalt har gjort det.

Det er kun når jeg ønsker at vise data'en at jeg skal lade den kører igennem ovenstående kode?

Så hvis jeg laver en kalender funktion på min side må jeg kun benytte mig af TIMESTAMP, hvis denne kalender funktion også skal benytte tidspunkt på dagen?
Avatar billede alex15 Nybegynder
01. februar 2010 - 16:36 #16
Eller bør jeg lave tiden om til den pågældende location før jeg indsætter dette i Databasen?

Puha, synes virkelig dette her er svært at forstå? - Eller er det bare mig som gør det mere besværgeligt end det er?
Avatar billede arne_v Ekspert
01. februar 2010 - 18:49 #17
Du boer gemme i databasen i UTC og saa formatere naar den skal vises.

Advanceret funktionalitet kraever ofte advanceret kode.
Avatar billede alex15 Nybegynder
01. februar 2010 - 20:32 #18
Ved godt at det er at presse situationen, men er det muligt at jeg kan få dig til at skrive lidt mere begynder venligt? Tror virkelig det her skal skæres ud i pap for mig ;-)

Du skrev i indlæg #3 følgende: 'TIMESTAMP gemmes altid internt i UTC.'.

Det vil altså sige at når jeg skriver følgende kode så gemmes den som UTC?

mysql_query("INSERT INTO `login` (`id`) values ('$ip')"); //Den sætter automatisk et tidspunkt ind i mit 'date' felt under min tabel 'login'. Dette tidspunkt svare dog ikke til UTC? Men derimod dansk tid, hvordan kan dette være? Skyldes dette at jeg har sat hak i 'Standardværdi' -> 'CURRENT_TIMESTAMP'?
Avatar billede arne_v Ekspert
02. februar 2010 - 04:05 #19
Næppe.

Jeg tror at den er gemt i UTC, men at du får konverteret til dansk tid når du henter ud !
Avatar billede alex15 Nybegynder
02. februar 2010 - 09:56 #20
Okay ja, men hvordan kan det være at jeg får det?

Jeg har lige prøvet at lave et forsøgs login her til morgen, og inde i databasen står der at jeg gjorde det på følgende tidspunkt:

2010-02-02 09:54:58

Tiden i England - Svarende til UTC, går jeg ud fra er dog:

2010-02-02 08:54:58

Så den må næsten gemme det i dansk tid og ikke UTC?

Kan du regne ud hvad det er som jeg gør galt?
Avatar billede arne_v Ekspert
03. februar 2010 - 04:02 #21
Nej. Det er hent som konverterer fra UTC til dansk tid.

Nemmeste workaround er måske at gemme det i en INT.

Det er ikke pænt, men så kan du kontrollere tidszone konverteringen i PHP.
Avatar billede alex15 Nybegynder
24. februar 2010 - 15:44 #22
Tror bare at jeg gemmer det i Databasen som du snakker om, altså som UTC.

Hvis jeg ønsker at vise indholdet fra Databasen gør jeg det på følgende måde:

echo $row['date']; //Kommer ud i dansk tid.

Hvordan kan det være at jeg ikke bare kan gøre følgende:

$yesterday = date(stripslashes($row1['date']), strtotime("-1 day")); echo "".$yesterday."";

Så jeg på den måde også ville kunne vise tiden som jeg havde lyst til?
Avatar billede alex15 Nybegynder
24. februar 2010 - 16:33 #23
Sådan, nu har jeg fundet ud af hvordan jeg får det hele til at gå op i en højere enhen, så hvis du lige smider et svar, så får du dine point? :-) Så smider jeg også lige det smalet svar ud nemlig, så andre kan få glæde af det.
Avatar billede alex15 Nybegynder
24. februar 2010 - 16:39 #24
SVAR:

1. Gemmer tid på normalvis ind i databasen, så der ikke er noget forskel om brugeren er logget ind i en klub i USA eller Danmark.

2. Når brugeren logger ind i den pågældende klub, bliver der fra databasen langt den pågældende tidszone (+1, +4 mv.) ned i følgende $_SESSION['cccbookingtimezonevalue'] - afhængig af hvor klubber selvfølgelig er placeret i verden.

3. Når jeg så ønsker at vise en nyhed fra databasen, herunder hvornår det er oprettet skriver jeg følgende kode:


echo stripslashes(date('Y-m-d H:i:s',strtotime("".$row['date']." ".$_SESSION['cccbookingtimezonevalue']." hours")));

--- Eksempel ---

echo $row['date'];

//2010-02-24 14:32:53

echo stripslashes(date('Y-m-d H:i:s',strtotime("".$row['date']." ".$_SESSION['cccbookingtimezonevalue']." hours")));


//2010-02-24 13:32:53

... Afslutningsvis ...

Håber at andre kan bruge ovenstående metode. Og 1000 tak for hjælpen Arne_v.
Avatar billede arne_v Ekspert
25. februar 2010 - 00:51 #25
svar
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Computerworld tilbyder specialiserede kurser i database-management

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester