Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Krótka historia czasu
Tomasz Nurkiewicz
 | 
2013­07­06T11:40:00.000Z
nurkiewicz@gmail.com @tnurkiewicz
Tomasz Nurkiewicz
 | 
6+ lat z Javą
Scala, JavaScript, Clojure...
Back­end, analiza i wizualizacja danych
 | 
Niegdyś akty...
Zły dzień Microsoftu
 
blogs.msdn.com/b/windowsazure/archive/2012/03/09/summary­of­windows­azure­service­disruption­on­feb...
Wynik programu?
Java:
C#:
Calendar cal = new GregorianCalendar(2012, FEBRUARY, 29, 15, 0);
cal.add(YEAR, 1);
System.out.pr...
28. lutego 2013, 15:00
29. lutego 2013, 15:00
1. marca 2013, 00:00
1. marca 2013, 15:00
IllegalArgumentException
True story
“[...] zgodnie z Regulaminem [...] odsetki nalicza się za faktyczną
liczbę dni pozostawania środków na koncie [...
Zła sekunda Linuksa
 
www.greenprophet.com/2012/07/leap­second­bug­consumes­megawatts­of­electricity/
Sekundy przestępne
 
en.wikipedia.org/wiki/Leap_second
Inne błędy
Problem roku 2000 (Y2K)
Problem roku 2011 (Taiwan)
Problem roku 2038 (Integer.MAX_VALUE)
Problem roku 2042 (IBM...
Zrozumieć domenę problemu
...każdego
Reprezentacja czasu
 
www.edali.org/persistence­of­memory.jsp
Ilość sekund od arbitralnego momentu
System kalendarzowy
Oś czasu
Czas "0"?
Data Wykorzystywana w
0. stycznia 0 MATLAB
1. stycznia 0 Symbian, Turbo DB
1. stycznia 1 Microsoft .NET, Go
1. s...
java.util.Date
:
vs.
:
en.wikipedia.org/wiki/Calendar_date
“A date in a calendar is a reference to a particular day
repres...
Strefy czasowe
java.util.Timezone
Różnica czasu między Warszawą a Sydney?
 
www.travel.com.hk/region/timezone.htm
Czas letni (Daylight saving time)
 
en.wikipedia.org/wiki/Daylight_saving_time
Czas letni
Zima → Lato Lato → Zima
en.wikipedia.org/wiki/Daylight_saving_time
...a zatem?
 
www.travel.com.hk/region/timezone.htm
Reprezentacja
ŹLE!
final TimeZone tz = TimeZone.getTimeZone("Europe/Warsaw");
TimeZone.getTimeZone("GMT+01:00");
TimeZone....
Data kalendarzowa
java.util.Calendar
Lata przestępne - ŹLE!
def leapYear(year: Int): Boolean =
year % 4 == 0
Lata przestępne - od biedy
def leapYear(year: Int): Boolean =
(year % 4 == 0 && year % 100 != 0) ||
(year % 400 == 0)
Lata przestępne
def leapYear(year: Int): Boolean =
new GregorianCalendar(year, JANUARY, 1).
getActualMaximum(DAY_OF_YEAR) ...
Zagadka
Calendar c = Calendar.getInstance();
System.out.println(c.get(Calendar.YEAR));
Mamy (gregoriański) rok 2013
A tymczasem w Tajlandii...
...i w Japonii...
$ java ...
2013
$ java -Duser.country=TH -Duser....
Lepiej:
Jeszcze lepiej:
Na wszelki wypadek...
Calendar c = new GregorianCalendar();
Calendar c = new GregorianCalendar(tim...
Dateczy Calendar?
"...po innym zdarzeniu"
"...w ciągu 10 sekund"
"...w ciągu godziny"
"...w ciągu 24 godzin"
"...w ciągu j...
Praktyka
Joda Time
final DateTime yearLater = new DateTime(2012, 2, 29, 15, 0).plusYears(1);
joda­time.sourceforge.net
Joda Time w JAX-WS
import org.joda.time.DateTime;
import javax.xml.bind.DatatypeConverter;
public class XsdJodaTimeConvert...
JAX-WS: plik .xjb
<bindings version="1.0" xmlns="http://java.sun.com/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSche...
Joda Time w JPA 2.1
import org.joda.time.Instant;
import javax.persistence.AttributeConverter;
import javax.persistence.Co...
Testowanie - narzędzia
Kontrolowane źródło czasu ( )
"Egzotyczna" domyślna strefa czasowa
Nie śpij! (Thread.sleep()), 
Sca...
Testowanie - przypadki
Początek/koniec miesiąca/roku
Dni powszednie i weekendy
29 lutego
Strefy czasowe, czas letni
ScalaCheck i ScalaTest
Negatywny rezultat
implicit override val generatorDrivenConfig =
PropertyCheckConfig(minSuccessful ...
Zdarzenia w przyszłości
,  , ...
Quartz
JMS
Activiti jBPM
Quartz scheduler
newTrigger()
.startAt(futureDate(1, YEAR))
.build();
quartz­scheduler.org/documentation/quartz­2.1.x/tuto...
JMS z opóźnieniem
MessageProducer producer = session.createProducer(destination);
TextMessage message = session.createText...
Bonus / Computus
(defn easter [year]
(let [
a (mod year 19)
b (Math/floor (/ year 100))
c (mod year 100)
d (Math/floor (/ ...
Bugi, więcej bugów...
1.  "Due to the lack of [time] synchronization [...] a car bomb went off [...] one hour earlier than...
Przydatne i ciekawe
1.   ­ wszystko o czasie
2.   ­ czas uniksowy
3.   ­ kanwa tej prezentacji
4.   ­ definicje TAI, UT, U...
Dziękuję za poświęcony... czas!
 
Twitter: 
nurkiewicz@gmail.com
@tnurkiewicz
nurkiewicz.github.io/talks/confitura2013
Upcoming SlideShare
Loading in …5
×

Krótka historia czasu - Confitura 2013

2,040 views

Published on

Jaka jest różnica czasu między Warszawą a Sydney? Odpowiedź na to pytanie jest zaskakująco trudna. Równie zaskakującym jest jak wielu programistów tej trudności nie dostrzega. Niby po co? Bo niemal co roku na światło dziennie wypływają zawstydzające błędy w oprogramowaniu, wynikające z niewiedzy bądź lekkomyślnego traktowania... czasu w systemach komputerowych.

Podczas tej prezentacji spróbuję pokazać, jak ważne jest świadome operowanie czasem podczas pisania oprogramowania. Nie będziemy (prawie) narzekali na klasę java.util.Date, ale skupimy się na fundamentalnych nieporozumieniach i błędach. Zobaczymy w przykładach fatalne skutki beztroskiego i nieumiejętnego obchodzenia się z czasem.

Nauczymy się także jak przechowywać, przesyłać i przetwarzać czas oraz jak testować systemy zależne od czasu (czyli w zasadzie wszystkie). Nie spodziewajcie się eksploracji takiego czy innego API. Skupimy się raczej na zrozumieniu praw rządzących upływem czasu i ich odpowiednim modelowaniem w naszych programach.

Published in: Technology
  • Be the first to comment

  • Be the first to like this

Krótka historia czasu - Confitura 2013

  1. 1. Krótka historia czasu Tomasz Nurkiewicz  |  2013­07­06T11:40:00.000Z nurkiewicz@gmail.com @tnurkiewicz
  2. 2. Tomasz Nurkiewicz  |  6+ lat z Javą Scala, JavaScript, Clojure... Back­end, analiza i wizualizacja danych  |  Niegdyś aktywny na  Trzeci raz na Javarsovii/Confiturze Pracuję w Oslo ( ) nurkiewicz.blogspot.com nurkiewicz@gmail.com @tnurkiewicz scala.net.pl github.com/nurkiewicz StackOverflow we are hiring!
  3. 3. Zły dzień Microsoftu   blogs.msdn.com/b/windowsazure/archive/2012/03/09/summary­of­windows­azure­service­disruption­on­feb­29th­2012.aspx
  4. 4. Wynik programu? Java: C#: Calendar cal = new GregorianCalendar(2012, FEBRUARY, 29, 15, 0); cal.add(YEAR, 1); System.out.println(cal.getTime()); DateTime cal = new DateTime(2012, 2, 29, 15, 0, 0).AddYears(1); Console.WriteLine(cal);
  5. 5. 28. lutego 2013, 15:00 29. lutego 2013, 15:00 1. marca 2013, 00:00 1. marca 2013, 15:00 IllegalArgumentException
  6. 6. True story “[...] zgodnie z Regulaminem [...] odsetki nalicza się za faktyczną liczbę dni pozostawania środków na koncie [...] z tym, że przyjmuje się, że rok liczy 365 dni. Rok 2012 liczy 366 dni, dlatego też  odsetki za dzień 29 lutego nie naliczają się. Z serdecznymi pozdrowieniami, [pewien] Bank” samcik.blox.pl/2012/03/Dzien­ktorego­nie­ma­Sprawdz­co­bank­wykreslil.html
  7. 7. Zła sekunda Linuksa   www.greenprophet.com/2012/07/leap­second­bug­consumes­megawatts­of­electricity/
  8. 8. Sekundy przestępne   en.wikipedia.org/wiki/Leap_second
  9. 9. Inne błędy Problem roku 2000 (Y2K) Problem roku 2011 (Taiwan) Problem roku 2038 (Integer.MAX_VALUE) Problem roku 2042 (IBM S/370) Problem roku 2107 (MS­DOS FAT) Problem 9. września '99 (9/9/99) en.wikipedia.org/wiki/Time_formatting_and_storage_bugs
  10. 10. Zrozumieć domenę problemu ...każdego
  11. 11. Reprezentacja czasu   www.edali.org/persistence­of­memory.jsp
  12. 12. Ilość sekund od arbitralnego momentu System kalendarzowy
  13. 13. Oś czasu
  14. 14. Czas "0"? Data Wykorzystywana w 0. stycznia 0 MATLAB 1. stycznia 0 Symbian, Turbo DB 1. stycznia 1 Microsoft .NET, Go 1. stycznia 1601 NTFS, COBOL, Win32/Win64 1. stycznia 1753 Microsoft SQL Server 31. grudnia 1840 MUMPS 17. listopada 1858 VMS, United States Naval Observatory, DVB SI, astronomia 30. grudnia 1899 Microsoft COM DATE, Object Pascal 0. stycznia 1900 Microsoft Excel, Lotus 1­2­3 1. stycznia 1900 NTP, IBM CICS, Mathematica, RISC OS, Common Lisp 1. stycznia 1904 LabVIEW, Mac OS 9, Palm OS, MP4 1. stycznia 1950 SEGA Dreamcast Data Wykorzystywana w 1. stycznia 1960 S­Plus, SAS 31. grudnia 1967 Pick OS 1. stycznia 1970 Linux, Mac OS X, C, Java, JavaScript, Perl, PHP, Python, Tcl, ActionScript 1. stycznia 1978 AmigaOS 1. stycznia 1980 DOS, OS/2, FAT16 I FAT32, VOS 6. stycznia 1980 Qualcomm BREW, GPS 1. stycznia 1981 Acorn NetFS 1. stycznia 1984 CiA® CANopen® 22. sierpnia 1999 Satelita Galileo 1. stycznia 2000 PostgreSQL, AppleSingle, AppleDouble 1. stycznia 2001 Apple Cocoa   en.wikipedia.org/wiki/Epoch_date
  15. 15. java.util.Date : vs. : en.wikipedia.org/wiki/Calendar_date “A date in a calendar is a reference to a particular day represented within a calendar system. [...] A particular day may be represented by a different date in another calendar” docs.oracle.com/javase/7/docs/api/java/util/Date.html “The class Date represents a specific instant in time, with millisecond precision.”
  16. 16. Strefy czasowe java.util.Timezone
  17. 17. Różnica czasu między Warszawą a Sydney?   www.travel.com.hk/region/timezone.htm
  18. 18. Czas letni (Daylight saving time)   en.wikipedia.org/wiki/Daylight_saving_time
  19. 19. Czas letni Zima → Lato Lato → Zima en.wikipedia.org/wiki/Daylight_saving_time
  20. 20. ...a zatem?   www.travel.com.hk/region/timezone.htm
  21. 21. Reprezentacja ŹLE! final TimeZone tz = TimeZone.getTimeZone("Europe/Warsaw"); TimeZone.getTimeZone("GMT+01:00"); TimeZone.getTimeZone("Europe/warsaw");
  22. 22. Data kalendarzowa java.util.Calendar
  23. 23. Lata przestępne - ŹLE! def leapYear(year: Int): Boolean = year % 4 == 0
  24. 24. Lata przestępne - od biedy def leapYear(year: Int): Boolean = (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)
  25. 25. Lata przestępne def leapYear(year: Int): Boolean = new GregorianCalendar(year, JANUARY, 1). getActualMaximum(DAY_OF_YEAR) > 365
  26. 26. Zagadka Calendar c = Calendar.getInstance(); System.out.println(c.get(Calendar.YEAR));
  27. 27. Mamy (gregoriański) rok 2013 A tymczasem w Tajlandii... ...i w Japonii... $ java ... 2013 $ java -Duser.country=TH -Duser.language=th ... 2556 $ java -Duser.country=JP -Duser.language=ja -Duser.variant=JP ... 25
  28. 28. Lepiej: Jeszcze lepiej: Na wszelki wypadek... Calendar c = new GregorianCalendar(); Calendar c = new GregorianCalendar(timeZone); Calendar c = new GregorianCalendar(timeZone, locale);
  29. 29. Dateczy Calendar? "...po innym zdarzeniu" "...w ciągu 10 sekund" "...w ciągu godziny" "...w ciągu 24 godzin" "...w ciągu jednego dnia" "...w 2013 roku" "...po 17:00" "...w piątek"
  30. 30. Praktyka
  31. 31. Joda Time final DateTime yearLater = new DateTime(2012, 2, 29, 15, 0).plusYears(1); joda­time.sourceforge.net
  32. 32. Joda Time w JAX-WS import org.joda.time.DateTime; import javax.xml.bind.DatatypeConverter; public class XsdJodaTimeConverter { public static DateTime unmarshal(String dateTime) { final long millis = DatatypeConverter. parseDate(dateTime). getTimeInMillis(); return new DateTime(millis); } public static String marshal(DateTime calendar) { return DatatypeConverter.printDate( calendar.toGregorianCalendar() ); } }
  33. 33. JAX-WS: plik .xjb <bindings version="1.0" xmlns="http://java.sun.com/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <globalBindings> <javaType xmlType="xs:dateTime" name="org.joda.time.DateTime" parseMethod="XsdJodaTimeConverter.unmarshal" printMethod="XsdJodaTimeConverter.marshal"/> </globalBindings> </bindings>
  34. 34. Joda Time w JPA 2.1 import org.joda.time.Instant; import javax.persistence.AttributeConverter; import javax.persistence.Converter; import java.util.Date; @Converter(autoApply = true) public class JodaTimeConverter implements AttributeConverter<Instant, Date> { @Override public Date convertToDatabaseColumn(Instant attr) { return attr != null? attr.toDate(): null; } @Override public Instant convertToEntityAttribute(Date dbData) { return dbData != null? new Instant(dbData): null; } }
  35. 35. Testowanie - narzędzia Kontrolowane źródło czasu ( ) "Egzotyczna" domyślna strefa czasowa Nie śpij! (Thread.sleep()),  ScalaCheck fake system clock Awaitility
  36. 36. Testowanie - przypadki Początek/koniec miesiąca/roku Dni powszednie i weekendy 29 lutego Strefy czasowe, czas letni
  37. 37. ScalaCheck i ScalaTest Negatywny rezultat implicit override val generatorDrivenConfig = PropertyCheckConfig(minSuccessful = 10000, workers = 4) test("any date +1 year and -1 year should yield same date back") { check { random: Date => { val plusMinusYear = new GregorianCalendar plusMinusYear.setTime(random) plusMinusYear.add(YEAR, 1) plusMinusYear.add(YEAR, -1) random == plusMinusYear.getTime } } } Falsified after 2665 passed tests: arg0 = Mon Feb 29 03:21:22 CET 73843340
  38. 38. Zdarzenia w przyszłości ,  , ... Quartz JMS Activiti jBPM
  39. 39. Quartz scheduler newTrigger() .startAt(futureDate(1, YEAR)) .build(); quartz­scheduler.org/documentation/quartz­2.1.x/tutorials/tutorial­lesson­05
  40. 40. JMS z opóźnieniem MessageProducer producer = session.createProducer(destination); TextMessage message = session.createTextMessage("...hello, delayed!"); message.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, oneYearMillis); producer.send(message); http://activemq.apache.org/delay­and­schedule­message­delivery.html
  41. 41. Bonus / Computus (defn easter [year] (let [ a (mod year 19) b (Math/floor (/ year 100)) c (mod year 100) d (Math/floor (/ b 4)) e (mod b 4) f (Math/floor (/ (+ b 8) 25)) g (Math/floor (/ (inc (- b f)) 3)) h (mod (+ (- (+ (* 19 a) b) d g) 15) 30) i (Math/floor (/ c 4)) k (mod c 4) L (mod (- (+ 32 (* 2 e) (* 2 i)) h k) 7) m (Math/floor (/ (+ a (* 11 h) (* 22 L)) 451)) n (- (+ h L 114) (* 7 m)) month (dec (Math/floor (/ n 31))) day (inc (mod n 31))] (java.util.GregorianCalendar. year month day))) en.wikipedia.org/wiki/Computus
  42. 42. Bugi, więcej bugów... 1.  "Due to the lack of [time] synchronization [...] a car bomb went off [...] one hour earlier than expected" ( ) 2.  "F­22 Raptors [...] experienced multiple computer crashes coincident with their crossing of [...] the International Date Line" ( ) 3.  "Damage to a German steel facility occurred during a DST transition" ( ) 4.  5.  6.  Niesłuszne posądzenie o defraudację i kradzież ( ­ [37]) 7.  Katalog kilkuset błędów, stan na rok 2000 (!) ( ) catless.ncl.ac.uk/Risks/20.58.html#subj12 en.wikipedia.org/wiki/List_of_software_bugs en.wikipedia.org/wiki/Daylight_Savings_Time www.wired.com/wiredenterprise/2012/07/leap­second­bug­wreaks­havoc­with­java­ linux www.theregister.co.uk/2012/07/02/leap_second_crashes_airlines www.cs.tau.ac.il/~nachumd/horror.html www.csl.sri.com/users/neumann/cal.html
  43. 43. Przydatne i ciekawe 1.   ­ wszystko o czasie 2.   ­ czas uniksowy 3.   ­ kanwa tej prezentacji 4.   ­ definicje TAI, UT, UTC... 5.   ­ Samoa and Tokelau skip a day for dateline change www.timeanddate.com www.epochconverter.com www.odi.ch/prog/design/datetime.php tycho.usno.navy.mil/systime.html www.bbc.co.uk/news/world­asia­16351377
  44. 44. Dziękuję za poświęcony... czas!   Twitter:  nurkiewicz@gmail.com @tnurkiewicz nurkiewicz.github.io/talks/confitura2013

×