Does exist an "user friendly" Date text converter and/or formatter package?
I'd like to specify the format of certain dates, in the way you normally do this, it is... with a string such as 'dd/mm/yyyy' or 'dd/mmm/yyyy'. Date's #printOn:format: expects a different parameter, which seems really convoluted. [1] And because I'll convert back and forth from/to String I'd like to know if there is a parser (other than DateParser). Thank you! Esteban A. Maringolo [1] compared with popular casting/formatting functions found in other languages/dialects |
Check out ZTimestampFormatter (load ConfigurationOfZTimestamp). From the class comment:
=== I am ZTimestampFormat, an implementation of a textual representation for a timestamp, date or time that can be used for formatting or parsing. You instanciate me by specifying the textual format by example, based on a #reference timetamp. Each component of the example representation is numbered from largest to smallest unit: 1=year 2=month 3=dayInMonth 4=hour (16 in 24 hour format) 5=minute 6=second as in the ISO representation: 2001-02-03T16:05:06Z which is a Saterday. Example format strings can be found in my class accessing protocol or in the unit tests. To specifiy a format, you write the reference date so that it matches the representation that you want. (ZTimestampFormat fromString: 'SAT, FEB 03 2001 (16:05:06)') format: ZTimestamp now. I can be used for unabiguous, stricter parsing as well. (ZTimestampFormat fromString: '02/03/01 (16:05:06)') parse: '10/10/10 (12:01:01)'. The list of possible keys and their interpretation #formatSpecifications. I can translate month and weekday names to 4 different languages, English, French, German and Dutch. I can optionally use a timezone to convert UTC/GMT/Zulu timestamps to local time. === Sven On 02 Sep 2014, at 20:51, Esteban A. Maringolo <[hidden email]> wrote: > Does exist an "user friendly" Date text converter and/or formatter package? > > > I'd like to specify the format of certain dates, in the way you > normally do this, it is... with a string such as 'dd/mm/yyyy' or > 'dd/mmm/yyyy'. > > Date's #printOn:format: expects a different parameter, which seems > really convoluted. [1] > > And because I'll convert back and forth from/to String I'd like to > know if there is a parser (other than DateParser). > > Thank you! > > > Esteban A. Maringolo > > [1] compared with popular casting/formatting functions found in other > languages/dialects > |
Thank you. It is certainly better than the base parser.
But for formats I can't pass Date objects to #format:, I have to convert them to ZTimestamp before. Curiosity #1: Why did you use an example date string instead of using regular patterns like yyyy, dd, hh/hh24, etc? Regards! Esteban A. Maringolo 2014-09-02 16:07 GMT-03:00 Sven Van Caekenberghe <[hidden email]>: > Check out ZTimestampFormatter (load ConfigurationOfZTimestamp). From the class comment: > > === > I am ZTimestampFormat, an implementation of a textual representation for a timestamp, date or time that can be used for formatting or parsing. > > You instanciate me by specifying the textual format by example, based on a #reference timetamp. > Each component of the example representation is numbered from largest to smallest unit: > 1=year > 2=month > 3=dayInMonth > 4=hour (16 in 24 hour format) > 5=minute > 6=second > as in the ISO representation: > 2001-02-03T16:05:06Z which is a Saterday. > Example format strings can be found in my class accessing protocol or in the unit tests. > > To specifiy a format, you write the reference date so that it matches the representation that you want. > > (ZTimestampFormat fromString: 'SAT, FEB 03 2001 (16:05:06)') > format: ZTimestamp now. > > I can be used for unabiguous, stricter parsing as well. > > (ZTimestampFormat fromString: '02/03/01 (16:05:06)') > parse: '10/10/10 (12:01:01)'. > > The list of possible keys and their interpretation #formatSpecifications. > I can translate month and weekday names to 4 different languages, English, French, German and Dutch. > I can optionally use a timezone to convert UTC/GMT/Zulu timestamps to local time. > === > > Sven > > On 02 Sep 2014, at 20:51, Esteban A. Maringolo <[hidden email]> wrote: > >> Does exist an "user friendly" Date text converter and/or formatter package? >> >> >> I'd like to specify the format of certain dates, in the way you >> normally do this, it is... with a string such as 'dd/mm/yyyy' or >> 'dd/mmm/yyyy'. >> >> Date's #printOn:format: expects a different parameter, which seems >> really convoluted. [1] >> >> And because I'll convert back and forth from/to String I'd like to >> know if there is a parser (other than DateParser). >> >> Thank you! >> >> >> Esteban A. Maringolo >> >> [1] compared with popular casting/formatting functions found in other >> languages/dialects >> > > |
On 02 Sep 2014, at 21:39, Esteban A. Maringolo <[hidden email]> wrote: > Thank you. It is certainly better than the base parser. > But for formats I can't pass Date objects to #format:, I have to > convert them to ZTimestamp before. (ZTimestampFormat fromString: '2001/02/03') format: Date today. Can you give an example of what does not work for you ? > Curiosity #1: Why did you use an example date string instead of using > regular patterns like yyyy, dd, hh/hh24, etc? That is why the formatter/parser was written in the first place ;-) It is modelled after a Go standard library (http://golang.org/src/pkg/time/format.go) and some Ruby library I can't remember the name of. I implemented this as a proof of concept to see if/how it could be done. > Regards! > Esteban A. Maringolo > > > 2014-09-02 16:07 GMT-03:00 Sven Van Caekenberghe <[hidden email]>: >> Check out ZTimestampFormatter (load ConfigurationOfZTimestamp). From the class comment: >> >> === >> I am ZTimestampFormat, an implementation of a textual representation for a timestamp, date or time that can be used for formatting or parsing. >> >> You instanciate me by specifying the textual format by example, based on a #reference timetamp. >> Each component of the example representation is numbered from largest to smallest unit: >> 1=year >> 2=month >> 3=dayInMonth >> 4=hour (16 in 24 hour format) >> 5=minute >> 6=second >> as in the ISO representation: >> 2001-02-03T16:05:06Z which is a Saterday. >> Example format strings can be found in my class accessing protocol or in the unit tests. >> >> To specifiy a format, you write the reference date so that it matches the representation that you want. >> >> (ZTimestampFormat fromString: 'SAT, FEB 03 2001 (16:05:06)') >> format: ZTimestamp now. >> >> I can be used for unabiguous, stricter parsing as well. >> >> (ZTimestampFormat fromString: '02/03/01 (16:05:06)') >> parse: '10/10/10 (12:01:01)'. >> >> The list of possible keys and their interpretation #formatSpecifications. >> I can translate month and weekday names to 4 different languages, English, French, German and Dutch. >> I can optionally use a timezone to convert UTC/GMT/Zulu timestamps to local time. >> === >> >> Sven >> >> On 02 Sep 2014, at 20:51, Esteban A. Maringolo <[hidden email]> wrote: >> >>> Does exist an "user friendly" Date text converter and/or formatter package? >>> >>> >>> I'd like to specify the format of certain dates, in the way you >>> normally do this, it is... with a string such as 'dd/mm/yyyy' or >>> 'dd/mmm/yyyy'. >>> >>> Date's #printOn:format: expects a different parameter, which seems >>> really convoluted. [1] >>> >>> And because I'll convert back and forth from/to String I'd like to >>> know if there is a parser (other than DateParser). >>> >>> Thank you! >>> >>> >>> Esteban A. Maringolo >>> >>> [1] compared with popular casting/formatting functions found in other >>> languages/dialects >>> >> >> > |
Administrator
|
In reply to this post by Esteban A. Maringolo
I like the example concept because the user has less to remember (even if those date patterns are pretty well-known). Although, I noticed an example date of 10/10/14 - how does it decide which is the month and which the day?
Cheers,
Sean |
On 02 Sep 2014, at 23:15, Sean P. DeNigris <[hidden email]> wrote: > Esteban A. Maringolo wrote >> Curiosity #1: Why did you use an example date string instead of using >> regular patterns like yyyy, dd, hh/hh24, etc? > > I like the example concept because the user has less to remember (even if > those date patterns are pretty well-known). Although, I noticed an example > date of 10/10/14 - how does it decide which is the month and which the day? Hmm, that is not possible, where did you see that ? Maybe you got the example and the input mixed up ? You instantiate the format based on a example (#fromString:) and then you use that to either #parse: or #format: |
Administrator
|
Oh yeah, I did, but even the example in that case is ambiguous, no? (ZTimestampFormat fromString: '02/03/01 (16:05:06)') parse: '10/10/10 (12:01:01)'. How does it decide whether it's American i.e. Feb 3rd, or European i.e. Mar 2nd?
Cheers,
Sean |
Hi Sean,
On 03 Sep 2014, at 00:32, Sean P. DeNigris <[hidden email]> wrote: > Sven Van Caekenberghe-2 wrote >> Maybe you got the example and the input mixed up ? > > Oh yeah, I did, but even the example in that case is ambiguous, no? > > (ZTimestampFormat fromString: '02/03/01 (16:05:06)') > parse: '10/10/10 (12:01:01)'. > > How does it decide whether it's American i.e. Feb 3rd, or European i.e. Mar 2nd? No, it is not ambiguous. The positions in the pattern are not used to determine the meaning of the elements, only the values. For example, limited to date elements only: (ZTimestampFormat fromString: '02/03/01') format: Date today. => '09/03/14' (ZTimestampFormat fromString: '03/02/01') format: Date today. => '03/09/14' (ZTimestampFormat fromString: 'Feb 3, 2001') format: Date today. => 'Sep 3, 2014' (ZTimestampFormat fromString: '02-FEB-2001') format: Date today. => '09-SEP-2014' (ZTimestampFormat fromString: 'Saturday, Februari 3 ''01') format: Date today. => 'Wednesday, September 3 ''14' The reference date is 20010203 which was a Saturday, the recognised elements for dates are: '2001' yearFourDigits '01' yearTwoDigits '02001' yearFull '02' monthTwoDigits '2' month 'February' monthNameCapitalized 'february' monthNameLowercased 'FEBRUARY' monthNameUppercased 'Feb' monthNameAbbreviatedCapitalized 'feb' monthNameAbbreviatedLowercased 'FEB' monthNameAbbreviatedUppercased '3' day '_3' dayTwoDigitsSpacePadded '03' dayTwoDigits See #formatSpecifications, each of those has parse and format methods, like #format:yearTwoDigitsOn: and #parseYearTwoDigitsFrom: Sven |
Sven Van Caekenberghe wrote:
Hi Sean, On 03 Sep 2014, at 00:32, Sean P. DeNigris [hidden email] wrote:Sven Van Caekenberghe-2 wroteMaybe you got the example and the input mixed up ?Oh yeah, I did, but even the example in that case is ambiguous, no? (ZTimestampFormat fromString: '02/03/01 (16:05:06)') parse: '10/10/10 (12:01:01)'. How does it decide whether it's American i.e. Feb 3rd, or European i.e. Mar 2nd?No, it is not ambiguous. The positions in the pattern are not used to determine the meaning of the elements, only the values. Okay, but its ambiguous in the sense that, at a glance, without knowing the legend (even though you provided it), at least Sean and myself got confused. For me part of that confusion is that you said... > 1=year > 2=month > 3=dayInMonth > 4=hour (16 in 24 hour format) > 5=minute > 6=second but the example used 02=month 03=day In either case, its harder to remember which magnitude an arbitrary index number refers, than using the usual mnemonics like this... yy=year mm=month mmm=month name d=day of month dd=zero padded day of month hh=12 hour HH=24 hour etc... and thats just off the top of my head. I think most people are familiar with this. Alternatively, if you want to use numbers, the following would be more intuitive to anyone glancing at it without needing to know the legend. 99=year 12=month 31=day 24=24 hour 12=12 hour 60=minute ?=second. etc... btw, I missed the first part of the That interesting. With the call of #formatSpecifications from...For example, limited to date elements only: (ZTimestampFormat fromString: '02/03/01') format: Date today. => '09/03/14' (ZTimestampFormat fromString: '03/02/01') format: Date today. => '03/09/14' (ZTimestampFormat fromString: 'Feb 3, 2001') format: Date today. => 'Sep 3, 2014' (ZTimestampFormat fromString: '02-FEB-2001') format: Date today. => '09-SEP-2014' (ZTimestampFormat fromString: 'Saturday, Februari 3 ''01') format: Date today. => 'Wednesday, September 3 ''14' The reference date is 20010203 which was a Saturday, the recognised elements for dates are: '2001' yearFourDigits '01' yearTwoDigits '02001' yearFull '02' monthTwoDigits '2' month 'February' monthNameCapitalized 'february' monthNameLowercased 'FEBRUARY' monthNameUppercased 'Feb' monthNameAbbreviatedCapitalized 'feb' monthNameAbbreviatedLowercased 'FEB' monthNameAbbreviatedUppercased '3' day '_3' dayTwoDigitsSpacePadded '03' dayTwoDigits See #formatSpecifications, each of those has parse and format methods, like #format:yearTwoDigitsOn: and #parseYearTwoDigitsFrom: Sven ZTimestampFormat class >> initialize "Initialize this class, to be redone every time #formatSpecifications changes." Formats := Dictionary newFromPairs: self formatSpecifications. FormatKeys := Formats keys sorted: [ :x :y | x size >= y size ] it looks like the format specifications could almost be pluggable. What if /Formats/ was instead an instance variable, such that my project could provide an extention method like this... ZTimestampFormat class >> myFormatSpecifications ^ #( 'YYYY' yearFourDigits 'YY' yearTwoDigits 'MM' monthTwoDigits 'M' month 'Month' monthNameCapitalized 'month' monthNameLowercased 'MONTH' monthNameUppercased 'Mth' monthNameAbbreviatedCapitalized 'mth' monthNameAbbreviatedLowercased 'MTH' monthNameAbbreviatedUppercased 'D' day '_D' dayTwoDigitsSpacePadded 'DD' dayTwoDigits 'h' hour12 'hh' hour12TwoDigits 'HH' hour24TwoDigits 'PM' daypartUppercased 'pm' daypartLowercased 'm' minute 'mm' minuteTwoDigits 's' second 'ss' secondTwoDigits 'Z' timeZoneZ '+00:00' timeZone 'UTC' timeZoneAbbreviated 'UTCLong' timeZoneAbbreviatedLong 'Weekday' weekdayNameCapitalized 'weekday' weekdayNameLowercased 'WEEKDAY' weekdayNameUppercased 'Wday' weekdayNameAbbreviatedCapitalized 'wday' weekdayNameAbbreviatedLowercased 'WDAY' weekdayNameAbbreviatedUppercased ) so I could go something like... (ZTimestampFormat withSpecification: #myFormatSpecification fromString: 'MM/DD/YY') format: Date today. => '09/03/14' That would be coool! cheers -ben btw, I didn't understand how yearFull in this line... '02001' yearFull was different from yearFourDigits. |
In reply to this post by Sven Van Caekenberghe-2
Esteban A. Maringolo
2014-09-02 17:46 GMT-03:00 Sven Van Caekenberghe <[hidden email]>: > > On 02 Sep 2014, at 21:39, Esteban A. Maringolo <[hidden email]> wrote: > >> Thank you. It is certainly better than the base parser. >> But for formats I can't pass Date objects to #format:, I have to >> convert them to ZTimestamp before. > > (ZTimestampFormat fromString: '2001/02/03') format: Date today. > > Can you give an example of what does not work for you ? My own brain doesn't work. I don't know what I did yesterday, but it works as expected now :) | format | format := (ZTimestampFormat fromString: '03/02/2001') createDate. format parse: '03/09/2014'. format format: Date today The only thing I'd change is to throw a specific Exception instead of an AssertionFailure. But I'm handling parsing errors fine with AssertionFailure handlers anyway. >> Curiosity #1: Why did you use an example date string instead of using >> regular patterns like yyyy, dd, hh/hh24, etc? > > That is why the formatter/parser was written in the first place ;-) It is modelled after a Go standard library (http://golang.org/src/pkg/time/format.go) and some Ruby library I can't remember the name of. I implemented this as a proof of concept to see if/how it could be done. Fair enough. :) Thank you! |
In reply to this post by Ben Coman
On 03 Sep 2014, at 15:24, Ben Coman <[hidden email]> wrote: > Sven Van Caekenberghe wrote: >> Hi Sean, >> >> On 03 Sep 2014, at 00:32, Sean P. DeNigris >> <[hidden email]> >> wrote: >> >> >>> Sven Van Caekenberghe-2 wrote >>> >>> >>>> Maybe you got the example and the input mixed up ? >>>> >>>> >>> Oh yeah, I did, but even the example in that case is ambiguous, no? >>> >>> (ZTimestampFormat fromString: '02/03/01 (16:05:06)') >>> parse: '10/10/10 (12:01:01)'. >>> >>> How does it decide whether it's American i.e. Feb 3rd, or European i.e. Mar 2nd? >>> >>> >> >> No, it is not ambiguous. The positions in the pattern are not used to determine the meaning of the elements, only the values. >> > > Okay, but its ambiguous in the sense that, at a glance, without knowing the legend (even though you provided it), at least Sean and myself got confused. > > For me part of that confusion is that you said... > > 1=year > > 2=month > > 3=dayInMonth > > 4=hour (16 in 24 hour format) > > 5=minute > > 6=second > > but the example used > 02=month > 03=day No, it is not confusing: the rule is from largest to smallest unit, thus year, month, day, hour, minute and second. Which is the ISO 8601 representation order BTW, making the most scientific sense IMHO. > In either case, its harder to remember which magnitude an arbitrary index number refers, than using the usual mnemonics like this... > yy=year > mm=month > mmm=month name > d=day of month > dd=zero padded day of month > hh=12 hour > HH=24 hour > etc... and thats just off the top of my head. I think most people are familiar with this. > > Alternatively, if you want to use numbers, the following would be more intuitive to anyone glancing at it without needing to know the legend. > 99=year > 12=month > 31=day > 24=24 hour > 12=12 hour > 60=minute > ?=second. > etc... > > btw, I missed the first part of the >> For example, limited to date elements only: >> >> (ZTimestampFormat fromString: '02/03/01') format: Date today. => '09/03/14' >> >> (ZTimestampFormat fromString: '03/02/01') format: Date today. => '03/09/14' >> >> (ZTimestampFormat fromString: 'Feb 3, 2001') format: Date today. => 'Sep 3, 2014' >> >> (ZTimestampFormat fromString: '02-FEB-2001') format: Date today. => '09-SEP-2014' >> >> (ZTimestampFormat fromString: 'Saturday, Februari 3 ''01') format: Date today. => 'Wednesday, September 3 ''14' >> >> The reference date is 20010203 which was a Saturday, the recognised elements for dates are: >> >> '2001' yearFourDigits >> '01' yearTwoDigits >> '02001' yearFull >> '02' monthTwoDigits >> '2' month >> 'February' monthNameCapitalized >> 'february' monthNameLowercased >> 'FEBRUARY' monthNameUppercased >> 'Feb' monthNameAbbreviatedCapitalized >> 'feb' monthNameAbbreviatedLowercased >> 'FEB' monthNameAbbreviatedUppercased >> '3' day >> '_3' dayTwoDigitsSpacePadded >> '03' dayTwoDigits >> >> See #formatSpecifications, each of those has parse and format methods, like #format:yearTwoDigitsOn: and #parseYearTwoDigitsFrom: >> >> Sven >> >> >> >> >> >> >> >> >> > That interesting. With the call of #formatSpecifications from... > ZTimestampFormat class >> initialize > "Initialize this class, to be redone every time #formatSpecifications changes." > Formats := Dictionary newFromPairs: self formatSpecifications. > FormatKeys := Formats keys sorted: [ :x :y | x size >= y size ] > > it looks like the format specifications could almost be pluggable. What if /Formats/ was instead an instance variable, such that my project could provide an extention method like this... > ZTimestampFormat class >> myFormatSpecifications > ^ #( > 'YYYY' yearFourDigits > 'YY' yearTwoDigits > 'MM' monthTwoDigits > 'M' month > 'Month' monthNameCapitalized > 'month' monthNameLowercased > 'MONTH' monthNameUppercased > 'Mth' monthNameAbbreviatedCapitalized > 'mth' monthNameAbbreviatedLowercased > 'MTH' monthNameAbbreviatedUppercased > 'D' day > '_D' dayTwoDigitsSpacePadded > 'DD' dayTwoDigits > 'h' hour12 > 'hh' hour12TwoDigits > 'HH' hour24TwoDigits > 'PM' daypartUppercased > 'pm' daypartLowercased > 'm' minute > 'mm' minuteTwoDigits > 's' second > 'ss' secondTwoDigits > 'Z' timeZoneZ > '+00:00' timeZone > 'UTC' timeZoneAbbreviated > 'UTCLong' timeZoneAbbreviatedLong > 'Weekday' weekdayNameCapitalized > 'weekday' weekdayNameLowercased > 'WEEKDAY' weekdayNameUppercased > 'Wday' weekdayNameAbbreviatedCapitalized > 'wday' weekdayNameAbbreviatedLowercased > 'WDAY' weekdayNameAbbreviatedUppercased ) > > so I could go something like... > (ZTimestampFormat withSpecification: #myFormatSpecification fromString: 'MM/DD/YY') format: Date today. => '09/03/14' > > That would be coool! > cheers -ben Yes, making it totally pluggable, or at least provide both an example based one and a more classic one makes sense. I'll think about that. Good idea. But the whole concept of the example is that it is easy to remember. Or so it should be ;-) > btw, I didn't understand how yearFull in this line... > '02001' yearFull > was different from yearFourDigits. Some people insist on the fact that using 4 digit years is wrong (http://longnow.org) ;-) For printing, 2001 and 02001 are the same because there is a natural overflow, but for parsing this is not the case: 02001 means using all digits until a non-digit, while 2001 always takes 4, and 01 always takes 2. BTW, these specs are not perfectly deterministic/symmetrical. There are too many date/time formats and conventions. |
In reply to this post by Esteban A. Maringolo
On 03 Sep 2014, at 15:44, Esteban A. Maringolo <[hidden email]> wrote: > Esteban A. Maringolo > > > 2014-09-02 17:46 GMT-03:00 Sven Van Caekenberghe <[hidden email]>: >> >> On 02 Sep 2014, at 21:39, Esteban A. Maringolo <[hidden email]> wrote: >> >>> Thank you. It is certainly better than the base parser. >>> But for formats I can't pass Date objects to #format:, I have to >>> convert them to ZTimestamp before. >> >> (ZTimestampFormat fromString: '2001/02/03') format: Date today. >> >> Can you give an example of what does not work for you ? > > My own brain doesn't work. > I don't know what I did yesterday, but it works as expected now :) > > | format | > format := (ZTimestampFormat fromString: '03/02/2001') createDate. > format parse: '03/09/2014'. > format format: Date today OK > The only thing I'd change is to throw a specific Exception instead of > an AssertionFailure. > But I'm handling parsing errors fine with AssertionFailure handlers anyway. Yes, using #assert: was laziness in the prototyping phase, I try to improve that part. >>> Curiosity #1: Why did you use an example date string instead of using >>> regular patterns like yyyy, dd, hh/hh24, etc? >> >> That is why the formatter/parser was written in the first place ;-) It is modelled after a Go standard library (http://golang.org/src/pkg/time/format.go) and some Ruby library I can't remember the name of. I implemented this as a proof of concept to see if/how it could be done. > > Fair enough. :) > > > Thank you! |
In reply to this post by Sven Van Caekenberghe-2
Sven Van Caekenberghe wrote:
On 03 Sep 2014, at 15:24, Ben Coman [hidden email] wrote:Sven Van Caekenberghe wrote:Hi Sean, On 03 Sep 2014, at 00:32, Sean P. DeNigris [hidden email] wrote:Sven Van Caekenberghe-2 wroteMaybe you got the example and the input mixed up ?Oh yeah, I did, but even the example in that case is ambiguous, no? (ZTimestampFormat fromString: '02/03/01 (16:05:06)') parse: '10/10/10 (12:01:01)'. How does it decide whether it's American i.e. Feb 3rd, or European i.e. Mar 2nd?No, it is not ambiguous. The positions in the pattern are not used to determine the meaning of the elements, only the values.Okay, but its ambiguous in the sense that, at a glance, without knowing the legend (even though you provided it), at least Sean and myself got confused. For me part of that confusion is that you said...1=year 2=month 3=dayInMonth 4=hour (16 in 24 hour format) 5=minute 6=secondbut the example used 02=month 03=dayNo, it is not confusing: the rule is from largest to smallest unit, thus year, month, day, hour, minute and second. Which is the ISO 8601 representation order BTW, making the most scientific sense IMHO.In either case, its harder to remember which magnitude an arbitrary index number refers, than using the usual mnemonics like this... yy=year mm=month mmm=month name d=day of month dd=zero padded day of month hh=12 hour HH=24 hour etc... and thats just off the top of my head. I think most people are familiar with this. Alternatively, if you want to use numbers, the following would be more intuitive to anyone glancing at it without needing to know the legend. 99=year 12=month 31=day 24=24 hour 12=12 hour 60=minute ?=second. etc... btw, I missed the first part of theFor example, limited to date elements only: (ZTimestampFormat fromString: '02/03/01') format: Date today. => '09/03/14' (ZTimestampFormat fromString: '03/02/01') format: Date today. => '03/09/14' (ZTimestampFormat fromString: 'Feb 3, 2001') format: Date today. => 'Sep 3, 2014' (ZTimestampFormat fromString: '02-FEB-2001') format: Date today. => '09-SEP-2014' (ZTimestampFormat fromString: 'Saturday, Februari 3 ''01') format: Date today. => 'Wednesday, September 3 ''14' The reference date is 20010203 which was a Saturday, the recognised elements for dates are: '2001' yearFourDigits '01' yearTwoDigits '02001' yearFull '02' monthTwoDigits '2' month 'February' monthNameCapitalized 'february' monthNameLowercased 'FEBRUARY' monthNameUppercased 'Feb' monthNameAbbreviatedCapitalized 'feb' monthNameAbbreviatedLowercased 'FEB' monthNameAbbreviatedUppercased '3' day '_3' dayTwoDigitsSpacePadded '03' dayTwoDigits See #formatSpecifications, each of those has parse and format methods, like #format:yearTwoDigitsOn: and #parseYearTwoDigitsFrom: SvenThat interesting. With the call of #formatSpecifications from... ZTimestampFormat class >> initialize "Initialize this class, to be redone every time #formatSpecifications changes." Formats := Dictionary newFromPairs: self formatSpecifications. FormatKeys := Formats keys sorted: [ :x :y | x size >= y size ] it looks like the format specifications could almost be pluggable. What if /Formats/ was instead an instance variable, such that my project could provide an extention method like this... ZTimestampFormat class >> myFormatSpecifications ^ #( 'YYYY' yearFourDigits 'YY' yearTwoDigits 'MM' monthTwoDigits 'M' month 'Month' monthNameCapitalized 'month' monthNameLowercased 'MONTH' monthNameUppercased 'Mth' monthNameAbbreviatedCapitalized 'mth' monthNameAbbreviatedLowercased 'MTH' monthNameAbbreviatedUppercased 'D' day '_D' dayTwoDigitsSpacePadded 'DD' dayTwoDigits 'h' hour12 'hh' hour12TwoDigits 'HH' hour24TwoDigits 'PM' daypartUppercased 'pm' daypartLowercased 'm' minute 'mm' minuteTwoDigits 's' second 'ss' secondTwoDigits 'Z' timeZoneZ '+00:00' timeZone 'UTC' timeZoneAbbreviated 'UTCLong' timeZoneAbbreviatedLong 'Weekday' weekdayNameCapitalized 'weekday' weekdayNameLowercased 'WEEKDAY' weekdayNameUppercased 'Wday' weekdayNameAbbreviatedCapitalized 'wday' weekdayNameAbbreviatedLowercased 'WDAY' weekdayNameAbbreviatedUppercased ) so I could go something like... (ZTimestampFormat withSpecification: #myFormatSpecification fromString: 'MM/DD/YY') format: Date today. => '09/03/14' That would be coool! cheers -benYes, making it totally pluggable, or at least provide both an example based one and a more classic one makes sense. I'll think about that. Good idea. But the whole concept of the example is that it is easy to remember. Or so it should be ;-)btw, I didn't understand how yearFull in this line... '02001' yearFull was different from yearFourDigits.Some people insist on the fact that using 4 digit years is wrong (http://longnow.org) ;-) Thanks I understand. Now off-topic, I like this... "Our crowd curated library of long-term thinking will be filled with the best 3,500 volumes to restart civilization." I've sometimes had the urge to write a book on how to restart civilization. A sort of real-life optimum path to producing the pre-requisites to advance tech levels. The sort of thing you keep under the bed that is no use until the day you need it... For printing, 2001 and 02001 are the same because there is a natural overflow, but for parsing this is not the case: 02001 means using all digits until a non-digit, while 2001 always takes 4, and 01 always takes 2. BTW, these specs are not perfectly deterministic/symmetrical. There are too many date/time formats and conventions. |
In reply to this post by Sven Van Caekenberghe-2
> That is why the formatter/parser was written in the first place ;-) It is modelled after a Go standard library (http://golang.org/src/pkg/time/format.go) and some Ruby library I can't remember the name of. I implemented this as a proof of concept to see if/how it could be done.
> Hi sven and this is cool that you did it :) |
Free forum by Nabble | Edit this page |