SlideShare a Scribd company logo
1 of 44
Download to read offline
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ś 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!
Zły dzień Microsoftu
 
blogs.msdn.com/b/windowsazure/archive/2012/03/09/summary­of­windows­azure­service­disruption­on­feb­29th­2012.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: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 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
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 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
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. 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
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.”
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.getTimeZone("Europe/warsaw");
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) > 365
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.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);
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"
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 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.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;
}
}
Testowanie - narzędzia
Kontrolowane źródło czasu ( )
"Egzotyczna" domyślna strefa czasowa
Nie śpij! (Thread.sleep()), 
ScalaCheck
fake system clock
Awaitility
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 = 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
,  , ...
Quartz
JMS
Activiti jBPM
Quartz scheduler
newTrigger()
.startAt(futureDate(1, YEAR))
.build();
quartz­scheduler.org/documentation/quartz­2.1.x/tutorials/tutorial­lesson­05
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
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.  "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
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
Dziękuję za poświęcony... czas!
 
Twitter: 
nurkiewicz@gmail.com
@tnurkiewicz
nurkiewicz.github.io/talks/confitura2013

More Related Content

Similar to Krótka historia czasu - Confitura 2013

Mvc frontend-trug-02-2011
Mvc frontend-trug-02-2011Mvc frontend-trug-02-2011
Mvc frontend-trug-02-2011Rafal Piekarski
 
Krzysztof Moskwa - Podstawy metod zwinnych: jak to działa? Story points, czyl...
Krzysztof Moskwa - Podstawy metod zwinnych: jak to działa? Story points, czyl...Krzysztof Moskwa - Podstawy metod zwinnych: jak to działa? Story points, czyl...
Krzysztof Moskwa - Podstawy metod zwinnych: jak to działa? Story points, czyl...PMI Szczecin
 
Confitura 2018 - Sekretne życie jobów Sparkowych
Confitura 2018 - Sekretne życie jobów SparkowychConfitura 2018 - Sekretne życie jobów Sparkowych
Confitura 2018 - Sekretne życie jobów SparkowychMarcin Jasiński
 
Programowanie Równolegle - Parallel Extensions
Programowanie Równolegle - Parallel ExtensionsProgramowanie Równolegle - Parallel Extensions
Programowanie Równolegle - Parallel ExtensionsWojciech Grześkowiak
 
TGT#14 - @Before – Nie będę automatyzować @After – No dobra, to nie jest taki...
TGT#14 - @Before – Nie będę automatyzować @After – No dobra, to nie jest taki...TGT#14 - @Before – Nie będę automatyzować @After – No dobra, to nie jest taki...
TGT#14 - @Before – Nie będę automatyzować @After – No dobra, to nie jest taki...Trójmiejska Grupa Testerska
 
Podstawy AngularJS
Podstawy AngularJSPodstawy AngularJS
Podstawy AngularJSSages
 
AngularJS szkolenie wewnętrzne (into)
AngularJS szkolenie wewnętrzne (into)AngularJS szkolenie wewnętrzne (into)
AngularJS szkolenie wewnętrzne (into)Marcin Baran
 
4Developers 2015: Orleans - aplikacje, które skalują i dystrybuują się same -...
4Developers 2015: Orleans - aplikacje, które skalują i dystrybuują się same -...4Developers 2015: Orleans - aplikacje, które skalują i dystrybuują się same -...
4Developers 2015: Orleans - aplikacje, które skalują i dystrybuują się same -...PROIDEA
 
"Administrator z przypadku" - Jak działa SQL Server i jak o niego dbać
"Administrator z przypadku" - Jak działa SQL Server i jak o niego dbać"Administrator z przypadku" - Jak działa SQL Server i jak o niego dbać
"Administrator z przypadku" - Jak działa SQL Server i jak o niego dbaćBartosz Ratajczyk
 
Tworzenie, zaciemnianie i analiza złośliwego kodu JavaScript
Tworzenie, zaciemnianie i analiza złośliwego kodu JavaScriptTworzenie, zaciemnianie i analiza złośliwego kodu JavaScript
Tworzenie, zaciemnianie i analiza złośliwego kodu JavaScriptKrzysztof Kotowicz
 
Asynchroniczne testy JavaScript aplikacji webowych
Asynchroniczne testy JavaScript aplikacji webowychAsynchroniczne testy JavaScript aplikacji webowych
Asynchroniczne testy JavaScript aplikacji webowychFuture Processing
 
Angular 4 pragmatycznie
Angular 4 pragmatycznieAngular 4 pragmatycznie
Angular 4 pragmatycznieSages
 
Confitura 2015 - Code Quality Keepers @ Allegro
Confitura 2015 - Code Quality Keepers @ AllegroConfitura 2015 - Code Quality Keepers @ Allegro
Confitura 2015 - Code Quality Keepers @ Allegroallegro.tech
 
Poznańska grupa .Net spotkanie VI - Test Driven Development
Poznańska grupa .Net spotkanie VI - Test Driven DevelopmentPoznańska grupa .Net spotkanie VI - Test Driven Development
Poznańska grupa .Net spotkanie VI - Test Driven Developmentbartlomiej.szafko
 
[PL] Jak programować aby nie zwariować
[PL] Jak programować aby nie zwariować[PL] Jak programować aby nie zwariować
[PL] Jak programować aby nie zwariowaćJakub Marchwicki
 
Wprowadzenie do języka Swift, czyli nowe podejście do programowania aplikacji...
Wprowadzenie do języka Swift, czyli nowe podejście do programowania aplikacji...Wprowadzenie do języka Swift, czyli nowe podejście do programowania aplikacji...
Wprowadzenie do języka Swift, czyli nowe podejście do programowania aplikacji...The Software House
 
Bohater UI bez front end developera ?
Bohater UI bez front end developera ?Bohater UI bez front end developera ?
Bohater UI bez front end developera ?Quick-Solution
 
infoShare 2011 - Jacek Laskowski - Programowanie Funkcjonalne Funkcyjnie z Cl...
infoShare 2011 - Jacek Laskowski - Programowanie Funkcjonalne Funkcyjnie z Cl...infoShare 2011 - Jacek Laskowski - Programowanie Funkcjonalne Funkcyjnie z Cl...
infoShare 2011 - Jacek Laskowski - Programowanie Funkcjonalne Funkcyjnie z Cl...Infoshare
 

Similar to Krótka historia czasu - Confitura 2013 (20)

Mvc frontend-trug-02-2011
Mvc frontend-trug-02-2011Mvc frontend-trug-02-2011
Mvc frontend-trug-02-2011
 
Krzysztof Moskwa - Podstawy metod zwinnych: jak to działa? Story points, czyl...
Krzysztof Moskwa - Podstawy metod zwinnych: jak to działa? Story points, czyl...Krzysztof Moskwa - Podstawy metod zwinnych: jak to działa? Story points, czyl...
Krzysztof Moskwa - Podstawy metod zwinnych: jak to działa? Story points, czyl...
 
Confitura 2018 - Sekretne życie jobów Sparkowych
Confitura 2018 - Sekretne życie jobów SparkowychConfitura 2018 - Sekretne życie jobów Sparkowych
Confitura 2018 - Sekretne życie jobów Sparkowych
 
Programowanie Równolegle - Parallel Extensions
Programowanie Równolegle - Parallel ExtensionsProgramowanie Równolegle - Parallel Extensions
Programowanie Równolegle - Parallel Extensions
 
TGT#14 - @Before – Nie będę automatyzować @After – No dobra, to nie jest taki...
TGT#14 - @Before – Nie będę automatyzować @After – No dobra, to nie jest taki...TGT#14 - @Before – Nie będę automatyzować @After – No dobra, to nie jest taki...
TGT#14 - @Before – Nie będę automatyzować @After – No dobra, to nie jest taki...
 
Podstawy AngularJS
Podstawy AngularJSPodstawy AngularJS
Podstawy AngularJS
 
AngularJS szkolenie wewnętrzne (into)
AngularJS szkolenie wewnętrzne (into)AngularJS szkolenie wewnętrzne (into)
AngularJS szkolenie wewnętrzne (into)
 
4Developers 2015: Orleans - aplikacje, które skalują i dystrybuują się same -...
4Developers 2015: Orleans - aplikacje, które skalują i dystrybuują się same -...4Developers 2015: Orleans - aplikacje, które skalują i dystrybuują się same -...
4Developers 2015: Orleans - aplikacje, które skalują i dystrybuują się same -...
 
"Administrator z przypadku" - Jak działa SQL Server i jak o niego dbać
"Administrator z przypadku" - Jak działa SQL Server i jak o niego dbać"Administrator z przypadku" - Jak działa SQL Server i jak o niego dbać
"Administrator z przypadku" - Jak działa SQL Server i jak o niego dbać
 
Tworzenie, zaciemnianie i analiza złośliwego kodu JavaScript
Tworzenie, zaciemnianie i analiza złośliwego kodu JavaScriptTworzenie, zaciemnianie i analiza złośliwego kodu JavaScript
Tworzenie, zaciemnianie i analiza złośliwego kodu JavaScript
 
Asynchroniczne testy JavaScript aplikacji webowych
Asynchroniczne testy JavaScript aplikacji webowychAsynchroniczne testy JavaScript aplikacji webowych
Asynchroniczne testy JavaScript aplikacji webowych
 
Kickoff to Node.js
Kickoff to Node.jsKickoff to Node.js
Kickoff to Node.js
 
Angular 4 pragmatycznie
Angular 4 pragmatycznieAngular 4 pragmatycznie
Angular 4 pragmatycznie
 
Confitura 2015 - Code Quality Keepers @ Allegro
Confitura 2015 - Code Quality Keepers @ AllegroConfitura 2015 - Code Quality Keepers @ Allegro
Confitura 2015 - Code Quality Keepers @ Allegro
 
Poznańska grupa .Net spotkanie VI - Test Driven Development
Poznańska grupa .Net spotkanie VI - Test Driven DevelopmentPoznańska grupa .Net spotkanie VI - Test Driven Development
Poznańska grupa .Net spotkanie VI - Test Driven Development
 
[PL] Jak programować aby nie zwariować
[PL] Jak programować aby nie zwariować[PL] Jak programować aby nie zwariować
[PL] Jak programować aby nie zwariować
 
Benchmarking
Benchmarking Benchmarking
Benchmarking
 
Wprowadzenie do języka Swift, czyli nowe podejście do programowania aplikacji...
Wprowadzenie do języka Swift, czyli nowe podejście do programowania aplikacji...Wprowadzenie do języka Swift, czyli nowe podejście do programowania aplikacji...
Wprowadzenie do języka Swift, czyli nowe podejście do programowania aplikacji...
 
Bohater UI bez front end developera ?
Bohater UI bez front end developera ?Bohater UI bez front end developera ?
Bohater UI bez front end developera ?
 
infoShare 2011 - Jacek Laskowski - Programowanie Funkcjonalne Funkcyjnie z Cl...
infoShare 2011 - Jacek Laskowski - Programowanie Funkcjonalne Funkcyjnie z Cl...infoShare 2011 - Jacek Laskowski - Programowanie Funkcjonalne Funkcyjnie z Cl...
infoShare 2011 - Jacek Laskowski - Programowanie Funkcjonalne Funkcyjnie z Cl...
 

Krótka historia czasu - Confitura 2013