--- a/Date.st Sat Jun 06 06:39:31 2015 +0200
+++ b/Date.st Sun Jun 07 06:38:49 2015 +0200
@@ -298,7 +298,8 @@
"return a new Date, given the day-number starting with 0 at 1.Jan 0;
(i.e. 'Date fromDaysSince0:0' returns 1st Jan. 0).
Date asDaysSince0 is the reverse operation.
- Notice, that this is a private interface"
+ Notice, that this is a private interface.
+ Also notice: does not care for Gregorian/Julisn calendar change"
|year rest d yearIncrement yearAsDaysFrom0|
@@ -446,16 +447,266 @@
"
!
+readFrom:aStringOrStream format:aSqueakFormatArrayOrFormatString
+ "return a new Date, reading a printed representation from aStream.
+ aSqueakFormatArrayOrFormatString may either be a squeak formatArray
+ 1 day position (1, 2 or 3)
+ 2 month position (1..3)
+ 3 year position (1..3)
+ or a formatString (see printing instance protocol)."
+
+ ^ self
+ readFrom:aStringOrStream
+ format:aSqueakFormatArrayOrFormatString
+ onError:[ self conversionErrorSignal raise ]
+
+ "
+ Date readFrom:'19:11:1999' format:#( 1 2 3 )
+ Date readFrom:'19-nov-1999' format:#( 1 2 3 )
+ Date readFrom:'19:11:1999' format:#( 2 1 3 ) -> exception: wrong month
+ Date readFrom:'5:12:1999' format:#( 2 1 3 )
+ Date readFrom:'may-12-1999' format:#( 2 1 3 )
+ Date readFrom:'1999 may 12' format:#( 3 2 1 )
+ Date readFrom:'12/31/2001' format:#( 2 1 3 )
+ Date readFrom:' 31.08.2001' format:#( 1 2 3 )
+ Date readFrom:' 31.dec.2001' format:#( 1 2 3 )
+ Date readFrom:' 31.Dec.2001' format:#( 1 2 3 )
+ Date readFrom:' 31.dez.2001' format:#( 1 2 3 )
+
+ Date readFrom:'31/12/01' format:'%d %m %y' onError:'fail'
+ Date readFrom:'12/01' format:'%m %y' onError:'fail'
+ Date readFrom:'01' format:'%y' onError:'fail'
+ Date readFrom:'30.01' format:'%d %m' onError:'fail'
+ "
+
+ "Created: 16.11.1995 / 22:50:17 / cg"
+ "Modified: 8.10.1996 / 19:25:39 / cg"
+!
+
+readFrom:aStringOrStream format:aFormatStringOrSqueakFormatArray language:languageOrNil onError:exceptionBlock
+ "return a new Date, reading a printed representation from aStream.
+ aFormatStringOrSqueakFormatArray may either be a squeak formatArray
+ 1 day position (1, 2 or 3)
+ 2 month position (1..3)
+ 3 year position (1..3)
+ or a formatString (see printing instance protocol).
+ For now %d, %m, %monthName, %shortMonthName, %y, %Y, %y1900, %y2000, %y1950 and %y1980 are supported in the formatString.
+ y1900 converts 2-digit year YY into 19YY,
+ y2000 into 20YY.
+ y1950, y1980 and Y are special;
+ if the year is below 50/80/70, it is converted to 20YY, otherwise to 19YY.
+ The formatString can have any of these characters '-.:,;/' as separator.
+ The format may be preceeded by a single numeric length (as in %2d) to specify how many
+ characters to read.
+ The formatString can also use a space as separator (for ex. '%d %m %y') and any separator will be allowed.
+ However, when a character separator is defined, only that separator will be expected.
+ TODO: make this a general feature of all DateAndTime classes.
+ "
+
+ |str|
+
+ str := aStringOrStream readStream.
+
+ [
+ |day month year dayOfYear monthAndDay|
+
+ aFormatStringOrSqueakFormatArray isArray ifTrue:[
+ |arg|
+
+ arg := Array new:3.
+
+ 1 to:3 do:[:i||v|
+ [str peek isLetterOrDigit] whileFalse:[str next].
+
+ v := (str peek isDigit) ifTrue:[Integer readFrom:str]
+ ifFalse:[str nextAlphaNumericWord].
+ arg at:i put:v
+ ].
+ year := arg at:(aFormatStringOrSqueakFormatArray at:3).
+ day := arg at:(aFormatStringOrSqueakFormatArray at:1).
+ month := arg at:(aFormatStringOrSqueakFormatArray at:2).
+ ] ifFalse:[
+ |formatStream fc c sel somePartAssoc len lStr|
+
+ formatStream := aFormatStringOrSqueakFormatArray readStream.
+
+ [formatStream atEnd] whileFalse:[
+ fc := formatStream next.
+ fc == $% ifTrue:[
+ sel := ''.
+ len := nil.
+ (fc := formatStream peekOrNil) notNil ifTrue:[
+ fc isDigit ifTrue:[
+ len := fc digitValue.
+ formatStream next.
+ ]
+ ].
+
+ (fc := formatStream peekOrNil) notNil ifTrue:[
+ fc == $( ifTrue:[
+ formatStream next.
+ sel := formatStream upTo:$)
+ ] ifFalse:[
+ sel := sel , (formatStream throughAnyForWhich:[:ch | ch isLetter])
+ ]
+ ].
+ len notNil ifTrue:[
+ lStr := str next:len.
+ somePartAssoc := self readDatePartFrom:lStr readStream format:sel language:languageOrNil.
+ ] ifFalse:[
+ somePartAssoc := self readDatePartFrom:str format:sel language:languageOrNil.
+ ].
+ somePartAssoc key == #day ifTrue:[
+ day := somePartAssoc value.
+ ] ifFalse:[somePartAssoc key == #month ifTrue:[
+ month := somePartAssoc value.
+ ] ifFalse:[somePartAssoc key == #year ifTrue:[
+ year := somePartAssoc value.
+ ] ifFalse:[somePartAssoc key == #dayOfYear ifTrue:[
+ dayOfYear := somePartAssoc value.
+ ] ifFalse:[
+ self error:'unexpected date part'
+ ]]]].
+ ] ifFalse:[
+ fc == Character space ifTrue:[
+ "/ Skip most possible separator characters
+ "/ (if not enough, should check for isNationalAlphaNumeric instead)
+ [(c := str peek) isSeparator
+ or:[ '-.:,;/\|?<>[]{}()#@!!$&^+=~*_"`' includes:c]] whileTrue:[str next].
+ ] ifFalse:[
+ str skipSeparators.
+ str next ~= fc ifTrue:[^ exceptionBlock value].
+ str skipSeparators.
+ ]
+ ]
+ ].
+ ].
+
+ dayOfYear notNil ifTrue:[
+ monthAndDay := Date monthAndDayFromDayInYear:dayOfYear forYear:year.
+ month := (monthAndDay at:1).
+ day := (monthAndDay at:2).
+ ].
+
+ day isNil ifTrue:[ day := 1 ].
+ month isNil ifTrue:[ month := 1 ].
+ year isNil ifTrue:[ year := Date today year ].
+
+ (year between:0 and:99) ifTrue:[
+ year := UserPreferences current twoDigitDateHandler value:year.
+ ].
+ ^ self newDay:day month:month year:year.
+ ] on:Error do:[:ex| ^ exceptionBlock value].
+
+ "
+ Date readFrom:'31 December 1992' printFormat:#(1 2 3) onError:'fail'
+ Date readFrom:'19:11:1999' printFormat:#(1 2 3) onError:'fail'
+ Date readFrom:'December, 5 1992' printFormat:#(1 2 3) onError:'fail'
+ Date readFrom:'3-jan-95' printFormat:#(1 2 3) onError:'fail'
+ Date readFrom:'12/31/1992' printFormat:#(1 2 3) onError:'fail'
+ Date readFrom:'15.4.1992' printFormat:#(1 2 3) onError:'wrong date' -> german
+ Date readFrom:'10.4.1992' printFormat:#(1 2 3) onError:'fail' -> german
+ Date readFrom:'10.4.1992' printFormat:#(1 2 3) onError:['wrong date']
+ Date readFrom:'32.4.1992' printFormat:#(1 2 3) onError:['wrong date']
+ Date readFrom:'fooBar' printFormat:#(1 2 3) onError:['wrong date']
+ Date readFrom:'10.4' printFormat:#(1 2 3) onError:['wrong date']
+ Date readFrom:'10041999' printFormat:#(1 2 3) onError:['wrong date']
+
+ Date readFrom:'31/12/92' printFormat:#(1 2 3) onError:'fail'
+ Date readFrom:'31/12/01' printFormat:#(1 2 3) onError:'fail'
+
+ Date readFrom:'31/12/01' printFormat:'%d %m %y' onError:'fail'
+ Date readFrom:'12/01' printFormat:'%m %y' onError:'fail'
+ Date readFrom:'01' printFormat:'%y' onError:'fail'
+ Date readFrom:'30.01' printFormat:'%d %m' onError:'fail'
+ Date readFrom:'300180' printFormat:'%2d%2m%2y' onError:'fail'
+
+ Date readFrom:'300170' printFormat:'%2d%2m%2y' onError:'fail' - gives 2070 as year
+ Date readFrom:'300170' printFormat:'%2d%2m%2Y' onError:'fail' - gives 1970 as year
+ Date readFrom:'300169' printFormat:'%2d%2m%2y' onError:'fail' - gives 2069 as year
+ Date readFrom:'300169' printFormat:'%2d%2m%2Y' onError:'fail' - gives 2069 as year
+
+ Date readFrom:'300170' printFormat:'%2d%2m%2(y1950)' onError:'fail' - gives 1970 as year
+ Date readFrom:'300170' printFormat:'%2d%2m%2(y1980)' onError:'fail' - gives 2070 as year
+ Date readFrom:'300181' printFormat:'%2d%2m%2(y1980)' onError:'fail' - gives 1981 as year
+
+ Date readFrom:'2015103' printFormat:'%4y%3(dayOfYear)' onError:'fail'
+
+ Date readFrom:'3-3-1995' printFormat:'%d %m %y' language: #de onError:'fail'
+ Date readFrom:'3-März-1995' printFormat:'%d %monthName %y' language: #de onError:'fail'
+ Date readFrom:'3-mär-1995' printFormat:'%d %shortMonthName %y' language: #de onError:'fail'
+ Date readFrom:'3/mär/1995' printFormat:'%d %shortMonthName %y' language: #de onError:'fail'
+ Date readFrom:'3/mär/1995' printFormat:'%d-%shortMonthName-%y' language: #de onError:'fail'
+ Date readFrom:'3-dez-1995' printFormat:'%d %shortMonthName %y' language: #de onError:'fail'
+ Date readFrom:'3-Dez-1995' printFormat:'%d %shortMonthName %y' language: #de onError:'fail'
+ Date readFrom:'3-Dezember-1995' printFormat:'%d %monthName %y' language: #de onError:'fail'
+
+ "
+
+ "Created: 16.11.1995 / 22:50:17 / cg"
+ "Modified: 8.10.1996 / 19:25:39 / cg"
+!
+
+readFrom:aStringOrStream format:aSqueakFormatArrayOrFormatString onError:exceptionBlock
+ "return a new Date, reading a printed representation from aStream.
+ aSqueakFormatArrayOrFormatString may either be a squeak formatArray
+ 1 day position (1, 2 or 3)
+ 2 month position (1..3)
+ 3 year position (1..3)
+ or a formatString (see printing instance protocol).
+ All of the %-formats as in the printString are supported here.
+ (i.e. %d, %m and %y, %shortMonthName and %monthName)
+ In addition, %Y, %y1900, %y2000, %y1950 and %y1980 are supported:
+ y1900 converts 2-digit year YY into 19YY, y2000 into 20YY.
+ y1950, y1980 and Y are special; if the year is below 50/80/70, it is converted to 20YY, otherwise to 19YY.
+ TODO: make this a general feature of all DateAndTime classes.
+ "
+
+ ^ self
+ readFrom:aStringOrStream
+ format:aSqueakFormatArrayOrFormatString
+ language:nil
+ onError:exceptionBlock
+
+ "
+ Date readFrom:'31 December 1992' format:#(1 2 3) onError:'fail'
+ Date readFrom:'19:11:1999' format:#(1 2 3) onError:'fail'
+ Date readFrom:'December, 5 1992' format:#(1 2 3) onError:'fail'
+ Date readFrom:'3-jan-95' format:#(1 2 3) onError:'fail'
+ Date readFrom:'12/31/1992' format:#(1 2 3) onError:'fail'
+ Date readFrom:'15.4.1992' format:#(1 2 3) onError:'wrong date' -> german
+ Date readFrom:'10.4.1992' format:#(1 2 3) onError:'fail' -> german
+ Date readFrom:'10.4.1992' format:#(1 2 3) onError:['wrong date']
+ Date readFrom:'32.4.1992' format:#(1 2 3) onError:['wrong date']
+ Date readFrom:'fooBar' format:#(1 2 3) onError:['wrong date']
+ Date readFrom:'10.4' format:#(1 2 3) onError:['wrong date']
+ Date readFrom:'10041999' format:#(1 2 3) onError:['wrong date']
+
+ Date readFrom:'31/12/92' format:#(1 2 3) onError:'fail'
+ Date readFrom:'31/12/01' format:#(1 2 3) onError:'fail'
+
+ Date readFrom:'31/12/01' format:'%d %m %y' onError:'fail'
+ Date readFrom:'12/01' format:'%m %y' onError:'fail'
+ Date readFrom:'01' format:'%y' onError:'fail'
+ Date readFrom:'30.01' format:'%d %m' onError:'fail'
+ Date readFrom:'311201' format:'%2d%2m%2y' onError:'fail'
+ "
+
+ "Created: 16.11.1995 / 22:50:17 / cg"
+ "Modified: 8.10.1996 / 19:25:39 / cg"
+!
+
readFrom:aStringOrStream onError:exceptionBlock
"return a new Date, reading a printed representation from aStream.
Notice, that this is not the storeString format and
is different from the format expected by readFrom:.
+
BUG:
- This method handles american format (i.e. month/day/year),
- common format with letter month in the middle (10 December 2007)
+ For Smalltalk compatibility, this method handles american format (i.e. month/day/year),
+ the common format with letter month in the middle (10 December 2007)
and ISO format (yyyy-mm-dd) - as long as yyyy is > 12.
- It does not handle the german/french and other dd-mm-yyyy.
+ It does NOT handle the german/french and other dd-mm-yyyy formats.
use readFrom:printFormat:onError: for this."
^ [
@@ -519,212 +770,6 @@
"Modified: 8.10.1996 / 19:25:39 / cg"
!
-readFrom:aStringOrStream printFormat:aSqueakFormatArrayOrFormatString
- "return a new Date, reading a printed representation from aStream.
- aSqueakFormatArrayOrFormatString may either be a squeak formatArray
- 1 day position (1, 2 or 3)
- 2 month position (1..3)
- 3 year position (1..3)
- or a formatString (see printing instance protocol)."
-
- ^ self
- readFrom:aStringOrStream
- printFormat:aSqueakFormatArrayOrFormatString
- onError:[ self conversionErrorSignal raise ]
-
- "
- Date readFrom:'19:11:1999' printFormat:#( 1 2 3 )
- Date readFrom:'19-nov-1999' printFormat:#( 1 2 3 )
- Date readFrom:'19:11:1999' printFormat:#( 2 1 3 ) -> exception: wrong month
- Date readFrom:'5:12:1999' printFormat:#( 2 1 3 )
- Date readFrom:'may-12-1999' printFormat:#( 2 1 3 )
- Date readFrom:'1999 may 12' printFormat:#( 3 2 1 )
- Date readFrom:'12/31/2001' printFormat:#( 2 1 3 )
- Date readFrom:' 31.08.2001' printFormat:#( 1 2 3 )
- Date readFrom:' 31.dec.2001' printFormat:#( 1 2 3 )
- Date readFrom:' 31.Dec.2001' printFormat:#( 1 2 3 )
- Date readFrom:' 31.dez.2001' printFormat:#( 1 2 3 )
-
- Date readFrom:'31/12/01' printFormat:'%d %m %y' onError:'fail'
- Date readFrom:'12/01' printFormat:'%m %y' onError:'fail'
- Date readFrom:'01' printFormat:'%y' onError:'fail'
- Date readFrom:'30.01' printFormat:'%d %m' onError:'fail'
- "
-
- "Created: 16.11.1995 / 22:50:17 / cg"
- "Modified: 8.10.1996 / 19:25:39 / cg"
-!
-
-readFrom:aStringOrStream printFormat:aFormatStringOrSqueakFormatArray language:languageOrNil onError:exceptionBlock
- "return a new Date, reading a printed representation from aStream.
- aFormatStringOrSqueakFormatArray may either be a squeak formatArray
- 1 day position (1, 2 or 3)
- 2 month position (1..3)
- 3 year position (1..3)
- or a formatString (see printing instance protocol).
- For now %d, %m, %monthName, %shortMonthName and %y are supported in the formatString.
- The formatString can have any of these characters '-.:,;/' as separator.
- The formatString can also use a space as separator (for ex. '%d %m %y') and any separator will be allowed.
- However, when a character separator is defined, only that separator will be expected.
- TODO: make this a general feature of all DateAndTime classes.
- "
-
- |str|
-
- str := aStringOrStream readStream.
-
- [
- |day month year|
-
- aFormatStringOrSqueakFormatArray isArray ifTrue:[
- |arg|
-
- arg := Array new:3.
-
- 1 to:3 do:[:i||v|
- [str peek isLetterOrDigit] whileFalse:[str next].
-
- v := (str peek isDigit) ifTrue:[Integer readFrom:str]
- ifFalse:[str nextAlphaNumericWord].
- arg at:i put:v
- ].
- year := arg at:(aFormatStringOrSqueakFormatArray at:3).
- day := arg at:(aFormatStringOrSqueakFormatArray at:1).
- month := arg at:(aFormatStringOrSqueakFormatArray at:2).
- ] ifFalse:[
- |formatStream fc c sel somePartAssoc|
-
- formatStream := aFormatStringOrSqueakFormatArray readStream.
-
- [formatStream atEnd] whileFalse:[
- fc := formatStream next.
- fc == $% ifTrue:[
- sel := ''.
- (fc := formatStream peekOrNil) notNil ifTrue:[
- fc == $( ifTrue:[
- formatStream next.
- sel := formatStream upTo:$)
- ] ifFalse:[
- sel := sel , (formatStream throughAnyForWhich:[:ch | ch isLetter])
- ]
- ].
- somePartAssoc := self readDatePartFrom:str format:sel language:languageOrNil.
- somePartAssoc key == #day ifTrue:[
- day := somePartAssoc value.
- ] ifFalse:[somePartAssoc key == #month ifTrue:[
- month := somePartAssoc value.
- ] ifFalse:[somePartAssoc key == #year ifTrue:[
- year := somePartAssoc value.
- ] ifFalse:[
- self error:'unexpected date part'
- ]]].
- ] ifFalse:[
- fc == Character space ifTrue:[
- "/ Skip most possible separator characters
- "/ (if not enough, should check for isNationalAlphaNumeric instead)
- [(c := str peek) isSeparator
- or:[ '-.:,;/\|?<>[]{}()#@!!$&^+=~*_"`' includes:c]] whileTrue:[str next].
- ] ifFalse:[
- str skipSeparators.
- str next ~= fc ifTrue:[^ exceptionBlock value].
- str skipSeparators.
- ]
- ]
- ].
- ].
-
- day isNil ifTrue:[ day := 1 ].
- month isNil ifTrue:[ month := 1 ].
- year isNil ifTrue:[ year := Date today year ].
-
- (year between:0 and:99) ifTrue:[
- year := UserPreferences current twoDigitDateHandler value:year.
- ].
- ^ self newDay:day month:month year:year.
- ] on:Error do:[:ex| ^ exceptionBlock value].
-
- "
- Date readFrom:'31 December 1992' printFormat:#(1 2 3) onError:'fail'
- Date readFrom:'19:11:1999' printFormat:#(1 2 3) onError:'fail'
- Date readFrom:'December, 5 1992' printFormat:#(1 2 3) onError:'fail'
- Date readFrom:'3-jan-95' printFormat:#(1 2 3) onError:'fail'
- Date readFrom:'12/31/1992' printFormat:#(1 2 3) onError:'fail'
- Date readFrom:'15.4.1992' printFormat:#(1 2 3) onError:'wrong date' -> german
- Date readFrom:'10.4.1992' printFormat:#(1 2 3) onError:'fail' -> german
- Date readFrom:'10.4.1992' printFormat:#(1 2 3) onError:['wrong date']
- Date readFrom:'32.4.1992' printFormat:#(1 2 3) onError:['wrong date']
- Date readFrom:'fooBar' printFormat:#(1 2 3) onError:['wrong date']
- Date readFrom:'10.4' printFormat:#(1 2 3) onError:['wrong date']
- Date readFrom:'10041999' printFormat:#(1 2 3) onError:['wrong date']
-
- Date readFrom:'31/12/92' printFormat:#(1 2 3) onError:'fail'
- Date readFrom:'31/12/01' printFormat:#(1 2 3) onError:'fail'
-
- Date readFrom:'31/12/01' printFormat:'%d %m %y' onError:'fail'
- Date readFrom:'12/01' printFormat:'%m %y' onError:'fail'
- Date readFrom:'01' printFormat:'%y' onError:'fail'
- Date readFrom:'30.01' printFormat:'%d %m' onError:'fail'
-
- Date readFrom:'3-3-1995' printFormat:'%d %m %y' language: #de onError:'fail'
- Date readFrom:'3-März-1995' printFormat:'%d %monthName %y' language: #de onError:'fail'
- Date readFrom:'3-mär-1995' printFormat:'%d %shortMonthName %y' language: #de onError:'fail'
- Date readFrom:'3/mär/1995' printFormat:'%d %shortMonthName %y' language: #de onError:'fail'
- Date readFrom:'3/mär/1995' printFormat:'%d-%shortMonthName-%y' language: #de onError:'fail'
- Date readFrom:'3-dez-1995' printFormat:'%d %shortMonthName %y' language: #de onError:'fail'
- Date readFrom:'3-Dez-1995' printFormat:'%d %shortMonthName %y' language: #de onError:'fail'
- Date readFrom:'3-Dezember-1995' printFormat:'%d %monthName %y' language: #de onError:'fail'
-
- "
-
- "Created: 16.11.1995 / 22:50:17 / cg"
- "Modified: 8.10.1996 / 19:25:39 / cg"
-!
-
-readFrom:aStringOrStream printFormat:aSqueakFormatArrayOrFormatString onError:exceptionBlock
- "return a new Date, reading a printed representation from aStream.
- aSqueakFormatArrayOrFormatString may either be a squeak formatArray
- 1 day position (1, 2 or 3)
- 2 month position (1..3)
- 3 year position (1..3)
- or a formatString (see printing instance protocol).
- All of the %-formats as in the printString are supported here.
- (i.e. %d, %m and %y, %shortMonthName and %monthName)
- TODO: make this a general feature of all DateAndTime classes.
- "
-
- ^ self
- readFrom:aStringOrStream
- printFormat:aSqueakFormatArrayOrFormatString
- language:nil
- onError:exceptionBlock
-
- "
- Date readFrom:'31 December 1992' printFormat:#(1 2 3) onError:'fail'
- Date readFrom:'19:11:1999' printFormat:#(1 2 3) onError:'fail'
- Date readFrom:'December, 5 1992' printFormat:#(1 2 3) onError:'fail'
- Date readFrom:'3-jan-95' printFormat:#(1 2 3) onError:'fail'
- Date readFrom:'12/31/1992' printFormat:#(1 2 3) onError:'fail'
- Date readFrom:'15.4.1992' printFormat:#(1 2 3) onError:'wrong date' -> german
- Date readFrom:'10.4.1992' printFormat:#(1 2 3) onError:'fail' -> german
- Date readFrom:'10.4.1992' printFormat:#(1 2 3) onError:['wrong date']
- Date readFrom:'32.4.1992' printFormat:#(1 2 3) onError:['wrong date']
- Date readFrom:'fooBar' printFormat:#(1 2 3) onError:['wrong date']
- Date readFrom:'10.4' printFormat:#(1 2 3) onError:['wrong date']
- Date readFrom:'10041999' printFormat:#(1 2 3) onError:['wrong date']
-
- Date readFrom:'31/12/92' printFormat:#(1 2 3) onError:'fail'
- Date readFrom:'31/12/01' printFormat:#(1 2 3) onError:'fail'
-
- Date readFrom:'31/12/01' printFormat:'%d %m %y' onError:'fail'
- Date readFrom:'12/01' printFormat:'%m %y' onError:'fail'
- Date readFrom:'01' printFormat:'%y' onError:'fail'
- Date readFrom:'30.01' printFormat:'%d %m' onError:'fail'
- "
-
- "Created: 16.11.1995 / 22:50:17 / cg"
- "Modified: 8.10.1996 / 19:25:39 / cg"
-!
-
today
"return a date, representing today.
See also: Time now / Timestamp now."
@@ -1698,6 +1743,151 @@
self obsoleteMethodWarning:'use #leapYear: (2014-09)'.
^ self leapYear:yearInteger
+!
+
+readFrom:aStringOrStream printFormat:aSqueakFormatArrayOrFormatString
+ "OBSOLETE: kept for backward compatibility.
+ return a new Date, reading a printed representation from aStream.
+ aSqueakFormatArrayOrFormatString may either be a squeak formatArray
+ 1 day position (1, 2 or 3)
+ 2 month position (1..3)
+ 3 year position (1..3)
+ or a formatString (see printing instance protocol)."
+
+ ^ self
+ readFrom:aStringOrStream
+ format:aSqueakFormatArrayOrFormatString
+
+ "
+ Date readFrom:'19:11:1999' printFormat:#( 1 2 3 )
+ Date readFrom:'19-nov-1999' printFormat:#( 1 2 3 )
+ Date readFrom:'19:11:1999' printFormat:#( 2 1 3 ) -> exception: wrong month
+ Date readFrom:'5:12:1999' printFormat:#( 2 1 3 )
+ Date readFrom:'may-12-1999' printFormat:#( 2 1 3 )
+ Date readFrom:'1999 may 12' printFormat:#( 3 2 1 )
+ Date readFrom:'12/31/2001' printFormat:#( 2 1 3 )
+ Date readFrom:' 31.08.2001' printFormat:#( 1 2 3 )
+ Date readFrom:' 31.dec.2001' printFormat:#( 1 2 3 )
+ Date readFrom:' 31.Dec.2001' printFormat:#( 1 2 3 )
+ Date readFrom:' 31.dez.2001' printFormat:#( 1 2 3 )
+
+ Date readFrom:'31/12/01' printFormat:'%d %m %y' onError:'fail'
+ Date readFrom:'12/01' printFormat:'%m %y' onError:'fail'
+ Date readFrom:'01' printFormat:'%y' onError:'fail'
+ Date readFrom:'30.01' printFormat:'%d %m' onError:'fail'
+ "
+
+ "Created: 16.11.1995 / 22:50:17 / cg"
+ "Modified: 8.10.1996 / 19:25:39 / cg"
+!
+
+readFrom:aStringOrStream printFormat:aFormatStringOrSqueakFormatArray language:languageOrNil onError:exceptionBlock
+ "OBSOLETE: kept for backward compatibility
+ return a new Date, reading a printed representation from aStream.
+ aFormatStringOrSqueakFormatArray may either be a squeak formatArray
+ 1 day position (1, 2 or 3)
+ 2 month position (1..3)
+ 3 year position (1..3)
+ or a formatString (see printing instance protocol).
+ For now %d, %m, %monthName, %shortMonthName, %y, %y1900, %y2000, %y1950 and %y1980 are supported in the formatString.
+ y1900 converts 2-digit year YY into 19YY, y2000 into 20YY.
+ y1950 and y1980 are special; if the year is below 50/80, it is converted to 20YY, otherwise to 19YY.
+ The formatString can have any of these characters '-.:,;/' as separator.
+ The format may be preceeded by a single numeric length (as in %2d) to specify how many
+ characters to read.
+ The formatString can also use a space as separator (for ex. '%d %m %y') and any separator will be allowed.
+ However, when a character separator is defined, only that separator will be expected.
+ TODO: make this a general feature of all DateAndTime classes.
+ "
+
+ ^ self readFrom:aStringOrStream format:aFormatStringOrSqueakFormatArray language:languageOrNil onError:exceptionBlock
+
+
+ "
+ Date readFrom:'31 December 1992' format:#(1 2 3) onError:'fail'
+ Date readFrom:'19:11:1999' format:#(1 2 3) onError:'fail'
+ Date readFrom:'December, 5 1992' format:#(1 2 3) onError:'fail'
+ Date readFrom:'3-jan-95' format:#(1 2 3) onError:'fail'
+ Date readFrom:'12/31/1992' format:#(1 2 3) onError:'fail'
+ Date readFrom:'15.4.1992' format:#(1 2 3) onError:'wrong date' -> german
+ Date readFrom:'10.4.1992' format:#(1 2 3) onError:'fail' -> german
+ Date readFrom:'10.4.1992' format:#(1 2 3) onError:['wrong date']
+ Date readFrom:'32.4.1992' format:#(1 2 3) onError:['wrong date']
+ Date readFrom:'fooBar' format:#(1 2 3) onError:['wrong date']
+ Date readFrom:'10.4' format:#(1 2 3) onError:['wrong date']
+ Date readFrom:'10041999' format:#(1 2 3) onError:['wrong date']
+
+ Date readFrom:'31/12/92' format:#(1 2 3) onError:'fail'
+ Date readFrom:'31/12/01' format:#(1 2 3) onError:'fail'
+
+ Date readFrom:'31/12/01' format:'%d %m %y' onError:'fail'
+ Date readFrom:'12/01' format:'%m %y' onError:'fail'
+ Date readFrom:'01' format:'%y' onError:'fail'
+ Date readFrom:'30.01' format:'%d %m' onError:'fail'
+ Date readFrom:'300180' format:'%2d%2m%2y' onError:'fail'
+
+ Date readFrom:'300170' format:'%2d%2m%2y' onError:'fail' - gives 2070 as year
+ Date readFrom:'300170' format:'%2d%2m%2(y1950)' onError:'fail' - gives 1970 as year
+ Date readFrom:'300170' format:'%2d%2m%2(y1980)' onError:'fail' - gives 2070 as year
+ Date readFrom:'300181' format:'%2d%2m%2(y1980)' onError:'fail' - gives 1981 as year
+
+ Date readFrom:'3-3-1995' format:'%d %m %y' language: #de onError:'fail'
+ Date readFrom:'3-März-1995' format:'%d %monthName %y' language: #de onError:'fail'
+ Date readFrom:'3-mär-1995' format:'%d %shortMonthName %y' language: #de onError:'fail'
+ Date readFrom:'3/mär/1995' format:'%d %shortMonthName %y' language: #de onError:'fail'
+ Date readFrom:'3/mär/1995' format:'%d-%shortMonthName-%y' language: #de onError:'fail'
+ Date readFrom:'3-dez-1995' format:'%d %shortMonthName %y' language: #de onError:'fail'
+ Date readFrom:'3-Dez-1995' format:'%d %shortMonthName %y' language: #de onError:'fail'
+ Date readFrom:'3-Dezember-1995' format:'%d %monthName %y' language: #de onError:'fail'
+ "
+
+ "Created: 16.11.1995 / 22:50:17 / cg"
+ "Modified: 8.10.1996 / 19:25:39 / cg"
+!
+
+readFrom:aStringOrStream printFormat:aSqueakFormatArrayOrFormatString onError:exceptionBlock
+ "return a new Date, reading a printed representation from aStream.
+ aSqueakFormatArrayOrFormatString may either be a squeak formatArray
+ 1 day position (1, 2 or 3)
+ 2 month position (1..3)
+ 3 year position (1..3)
+ or a formatString (see printing instance protocol).
+ All of the %-formats as in the printString are supported here.
+ (i.e. %d, %m and %y, %shortMonthName and %monthName)
+ In addition, %y1900, %y2000, %y1950 and %y1980 are supported:
+ y1900 converts 2-digit year YY into 19YY, y2000 into 20YY.
+ y1950 and y1980 are special; if the year is below 50/80, it is converted to 20YY, otherwise to 19YY.
+ TODO: make this a general feature of all DateAndTime classes.
+ "
+
+ ^ self readFrom:aStringOrStream format:aSqueakFormatArrayOrFormatString onError:exceptionBlock
+
+ "
+ Date readFrom:'31 December 1992' format:#(1 2 3) onError:'fail'
+ Date readFrom:'19:11:1999' format:#(1 2 3) onError:'fail'
+ Date readFrom:'December, 5 1992' format:#(1 2 3) onError:'fail'
+ Date readFrom:'3-jan-95' format:#(1 2 3) onError:'fail'
+ Date readFrom:'12/31/1992' format:#(1 2 3) onError:'fail'
+ Date readFrom:'15.4.1992' format:#(1 2 3) onError:'wrong date' -> german
+ Date readFrom:'10.4.1992' format:#(1 2 3) onError:'fail' -> german
+ Date readFrom:'10.4.1992' format:#(1 2 3) onError:['wrong date']
+ Date readFrom:'32.4.1992' format:#(1 2 3) onError:['wrong date']
+ Date readFrom:'fooBar' format:#(1 2 3) onError:['wrong date']
+ Date readFrom:'10.4' format:#(1 2 3) onError:['wrong date']
+ Date readFrom:'10041999' format:#(1 2 3) onError:['wrong date']
+
+ Date readFrom:'31/12/92' format:#(1 2 3) onError:'fail'
+ Date readFrom:'31/12/01' format:#(1 2 3) onError:'fail'
+
+ Date readFrom:'31/12/01' format:'%d %m %y' onError:'fail'
+ Date readFrom:'12/01' format:'%m %y' onError:'fail'
+ Date readFrom:'01' format:'%y' onError:'fail'
+ Date readFrom:'30.01' format:'%d %m' onError:'fail'
+ Date readFrom:'311201' format:'%2d%2m%2y' onError:'fail'
+ "
+
+ "Created: 16.11.1995 / 22:50:17 / cg"
+ "Modified: 8.10.1996 / 19:25:39 / cg"
! !
!Date class methodsFor:'private'!
@@ -1805,7 +1995,7 @@
readDatePartFrom:str format:fmt language:languageOrNil
"read a single component (such as %shortName) from str"
- |dayName monthName day month year format string |
+ |dayName monthName day month year format string dayOfYear|
format := fmt.
string := str throughAnyForWhich:[:ch | ch isNationalAlphaNumeric].
@@ -1815,12 +2005,12 @@
dayName := string.
^ nil.
].
- (format sameAs:'d') ifTrue:[
+ ((format sameAs:'d') or:[format sameAs:'day']) ifTrue:[
day := Integer readFrom:string.
^ #day -> day
].
- (format sameAs:'m') ifTrue:[
+ ((format sameAs:'m') or:[format sameAs:'month']) ifTrue:[
month := Integer readFrom:string.
^ #month -> month
].
@@ -1837,21 +2027,64 @@
^ #month -> month
].
- format = 'y' ifTrue:[
+ format = 'y1900' ifTrue:[
+ year := Integer readFrom:string.
+ year < 100 ifTrue:[
+ ^ #year -> (year + 1900)
+ ].
+ ^ #year -> year
+ ].
+
+ format = 'y1950' ifTrue:[
+ "shift YY into 1950..2049; for 2k support of old date strings"
+ year := Integer readFrom:string.
+ year < 100 ifTrue:[
+ year < 50 ifTrue:[
+ ^ #year -> (year + 2000)
+ ].
+ ^ #year -> (year + 1900)
+ ].
+ ^ #year -> year
+ ].
+
+ format = 'y1980' ifTrue:[
+ "shift YY into 1980..2079; for 2k support of old date strings"
+ year := Integer readFrom:string.
+ year < 100 ifTrue:[
+ year < 80 ifTrue:[
+ ^ #year -> (year + 2000)
+ ].
+ ^ #year -> (year + 1900)
+ ].
+ ^ #year -> year
+ ].
+
+ (format = 'Y') ifTrue:[
+ "shift YY into 1970..2069; for 2k support of old date strings"
+ year := Integer readFrom:string.
+ year < 100 ifTrue:[
+ year < 70 ifTrue:[
+ ^ #year -> (year + 2000)
+ ].
+ ^ #year -> (year + 1900)
+ ].
+ ^ #year -> year
+ ].
+
+ ((format = 'y') or:[format sameAs:'year']) ifTrue:[
year := Integer readFrom:string.
year < 100 ifTrue:[
^ #year -> (year + 2000)
].
^ #year -> year
].
- format = 'Y' ifTrue:[
- year := Integer readFrom:string.
- year >= 100 ifTrue:[
- ^ #year -> year
- ].
- ^ #year -> (year + 2000)
+
+ (format sameAs:'dayOfYear') ifTrue:[
+ dayOfYear := Integer readFrom:string.
+ ^ #dayOfYear -> dayOfYear
].
- self error:'unknown format specifier'
+
+ self error:'unknown format specifier: ',format
! !
!Date class methodsFor:'private-instance creation'!
@@ -3103,12 +3336,15 @@
!Date methodsFor:'printing & storing'!
addPrintBindingsTo:aDictionary
+ "see comment in addPrintBindingsTo:language:"
+
self addPrintBindingsTo:aDictionary language:nil.
!
addPrintBindingsTo:aDictionary language:languageOrNil
"private print support: add bindings for printing to aDictionary.
- languageOrNil can only be #en or nil for the current language.
+ languageOrNil can only be #en or nil for the current language setting (Smalltalk language).
+
valid format items are:
%d - day, 01..31 0-padded to length 2
%m - month, 01..12 0-padded to length 2
@@ -3121,7 +3357,17 @@
%W - week in year - unpadded
%Y - year, last 2 digits only i.e. 99, 04 (danger: year 2k bug)
+ %Y1900 - year, last 2 digits of 19YY only i.e. 99, 04 (danger: year 2k bug)
+ raises an error, if the year is not in 1900..1999
+ %Y2000 - year, last 2 digits of 20YY only i.e. 01, 04 or 15
+ raises an error, if the year is not in 2000..2099
+ %Y1950 - year, last 2 digits of 19YY or 20YY only i.e. 01, 04 or 80
+ raises an error, if the year is not in 1950..2049
+ %Y1980 - year, last 2 digits of 19YY or 20YY only i.e. 01, 04 or 80
+ raises an error, if the year is not in 1980..2079
+
%(weekDay) - day in week (1->monday, 2->tuesday, ... ,7->sunday)
+ %(dayOfYear) - day in year (1..365/366)
%(dayName) - full day name
%(DayName) - full day name, first character uppercase
@@ -3148,7 +3394,7 @@
|day ds dsPadded0 dsPaddedB month ms msPadded0 msPaddedB
year weekInYear monthName shortMonthName
- dayInWeek dayOfWeek dayName shortDayName ws wsPadded0|
+ dayInWeek dayOfWeek dayName dayOfYear shortDayName ws wsPadded0|
day := self day.
ds := day printString.
@@ -3167,6 +3413,7 @@
dayInWeek := self dayInWeek. "/ 1 .. 7
dayOfWeek := self dayOfWeek. "/ 0 .. 6
+ dayOfYear := self dayOfYear. "/ 0 .. 6
monthName := self class nameOfMonth:(self month) language:languageOrNil.
dayName := self class nameOfDay:dayInWeek language:languageOrNil.
@@ -3197,6 +3444,26 @@
aDictionary at:$M put:ms.
aDictionary at:$y put:year.
aDictionary at:$Y put:((year \\ 100) printStringLeftPaddedTo:2 with:$0).
+ aDictionary at:#Y1950 put:[
+ (year between:1950 and:2049) ifFalse:[
+ self error:'year cannot be represented'
+ ].
+ (year between:1950 and:1999) ifTrue:[
+ (year - 1900) printStringLeftPaddedTo:2 with:$0
+ ] ifFalse:[
+ (year - 2000) printStringLeftPaddedTo:2 with:$0
+ ]
+ ].
+ aDictionary at:#Y1980 put:[
+ (year between:1980 and:2079) ifFalse:[
+ self error:'year cannot be represented'
+ ].
+ (year between:1980 and:1999) ifTrue:[
+ (year - 1900) printStringLeftPaddedTo:2 with:$0
+ ] ifFalse:[
+ (year - 2000) printStringLeftPaddedTo:2 with:$0
+ ]
+ ].
aDictionary at:$w put:wsPadded0.
aDictionary at:$W put:ws.
@@ -3213,6 +3480,7 @@
aDictionary at:#weekDay put:dayInWeek.
aDictionary at:#weekday put:dayInWeek.
aDictionary at:#weekDayUS put:dayOfWeek.
+ aDictionary at:#dayOfYear put:dayOfYear.
aDictionary at:#shortDayName put:(shortDayName := self class abbreviatedNameOfDay:(self dayInWeek) language:languageOrNil).
aDictionary at:#shortdayname put:shortDayName asLowercase.
@@ -3266,6 +3534,8 @@
Date today printOn:Transcript format:'%(DayName), %D%(nth) of %(MonthName), %y'
Date today printOn:Transcript format:'%(ShortDayName), %D-%(ShortMonthName)-%y'
Date today printOn:Transcript format:'%d%m%Y' (millenium bug format - danger)
+ Date today printOn:Transcript format:'%d%m%(Y1950)' (millenium bug partial workaround format - danger)
+ Date today printOn:Transcript format:'%d%m%(Y1980)' (millenium bug partial workaround format - danger)
Date today printOn:Transcript format:'Today is the %(weekDay) day of the week'
Date today printOn:Transcript format:'Today is %(year).%(monthRoman).%D' (hungarian format)
Date today printOn:Transcript format:'Today is %(D) %(monthRoman) %y' (poland)
@@ -3273,12 +3543,15 @@
Date today printOn:Transcript format:'Today is %(D)/%(mon)-%Y' (sweden)
Date today printOn:Transcript format:'Anno domini %(yearRoman)'
Date today printOn:Transcript format:'%y年%(mon)月%d日' (select a font, which can display those chars)
+ Date today printOn:Transcript format:'%(dayOfYear)'
"
+
"short form (as in blogs like www.stackoverflow, www.superuser etc.)
Date today printOn:Transcript format:'%(MonthName) %D ''%Y'
Timestamp now printOn:Transcript format:'%(MonthName) %D ''%Y at %h:%m'
"
- "
+
+ "Squeak format spec:
String streamContents:[:s |
Date today printOn:s format:#(1 2 3 $/ 1 2)
]
@@ -3475,11 +3748,11 @@
!Date class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic/Date.st,v 1.170 2015-05-17 20:49:07 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/Date.st,v 1.174 2015-06-06 11:18:11 cg Exp $'
!
version_CVS
- ^ '$Header: /cvs/stx/stx/libbasic/Date.st,v 1.170 2015-05-17 20:49:07 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/Date.st,v 1.174 2015-06-06 11:18:11 cg Exp $'
! !