Tomasz Nurkiewicz |
6+ lat z JavąScala, JavaScript, Clojure...Backend, analiza i wizualizacja danych
| Niegdyś aktywny na Trzeci raz na Javarsovii/ConfiturzePracuję w Oslo ( )
nurkiewicz.blogspot.com
[email protected] @tnurkiewicz
scala.net.pl github.com/nurkiewiczStackOverflow
we are hiring!
Zły dzień Microsoftu
blogs.msdn.com/b/windowsazure/archive/2012/03/09/summaryofwindowsazureservicedisruptiononfeb29th2012.aspx
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);
28. lutego 2013, 15:0029. lutego 2013, 15:001. marca 2013, 00:001. marca 2013, 15:00IllegalArgumentException
True story“[...] zgodnie z Regulaminem [...] odsetki nalicza się za faktyczną
liczbę dni pozostawania środków na koncie [...] z tym, żeprzyjmuje 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/DzienktoregoniemaSprawdzcobankwykreslil.html
Zła sekunda Linuksa
www.greenprophet.com/2012/07/leapsecondbugconsumesmegawattsofelectricity/
Inne błędyProblem roku 2000 (Y2K)Problem roku 2011 (Taiwan)Problem roku 2038 (Integer.MAX_VALUE)Problem roku 2042 (IBM S/370)Problem roku 2107 (MSDOS FAT)Problem 9. września '99 (9/9/99)
en.wikipedia.org/wiki/Time_formatting_and_storage_bugs
Zrozumieć domenę problemu...każdego
Reprezentacja czasu
www.edali.org/persistenceofmemory.jsp
Ilość sekund od arbitralnego momentuSystem 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. 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 123
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 SPlus, 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
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 maybe 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.”
Strefy czasowejava.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 → Zimaen.wikipedia.org/wiki/Daylight_saving_time
Reprezentacja
ŹLE!final TimeZone tz = TimeZone.getTimeZone("Europe/Warsaw");
TimeZone.getTimeZone("GMT+01:00");
TimeZone.getTimeZone("Europe/warsaw");
Data kalendarzowajava.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) > 365
ZagadkaCalendar 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.language=th ...2556
$ java -Duser.country=JP -Duser.language=ja -Duser.variant=JP ...25
Lepiej:
Jeszcze lepiej:
Na wszelki wypadek...
Calendar c = new GregorianCalendar();
Calendar c = new GregorianCalendar(timeZone);
Calendar c = new GregorianCalendar(timeZone, locale);
Date czy 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"
Praktyka
Joda Timefinal DateTime yearLater = new DateTime(2012, 2, 29, 15, 0).plusYears(1);
jodatime.sourceforge.net
Joda Time w JAX-WSimport 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() ); }}
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>
Joda Time w JPA 2.1import 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; }}
Testowanie - narzędziaKontrolowane źródło czasu ( )"Egzotyczna" domyślna strefa czasowaNie śpij! (Thread.sleep()), ScalaCheck
fake system clock
Awaitility
Testowanie - przypadkiPoczątek/koniec miesiąca/rokuDni powszednie i weekendy29 lutegoStrefy czasowe, czas letni
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
Zdarzenia w przyszłości, , ...
QuartzJMS
Activiti jBPM
Quartz schedulernewTrigger() .startAt(futureDate(1, YEAR)) .build();
quartzscheduler.org/documentation/quartz2.1.x/tutorials/tutoriallesson05
JMS z opóźnieniemMessageProducer producer = session.createProducer(destination);TextMessage message = session.createTextMessage("...hello, delayed!");message.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, oneYearMillis);producer.send(message);
http://activemq.apache.org/delayandschedulemessagedelivery.html
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
Bugi, więcej bugów...1. "Due to the lack of [time] synchronization [...] a car bomb went off [...] one hour earlier than
expected" ( )2. "F22 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_Timewww.wired.com/wiredenterprise/2012/07/leapsecondbugwreakshavocwithjavalinuxwww.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
Przydatne i ciekawe1. wszystko o czasie2. czas uniksowy3. kanwa tej prezentacji4. definicje TAI, UT, UTC...5. Samoa and Tokelau skip a day for dateline
change
www.timeanddate.comwww.epochconverter.comwww.odi.ch/prog/design/datetime.phptycho.usno.navy.mil/systime.htmlwww.bbc.co.uk/news/worldasia16351377
Dziękuję za poświęcony... czas!
Twitter: [email protected]
@tnurkiewicz
nurkiewicz.github.io/talks/confitura2013
Top Related