On 03 Sep 2014, at 15:24, Ben Coman <b...@openinworld.com> wrote: > Sven Van Caekenberghe wrote: >> Hi Sean, >> >> On 03 Sep 2014, at 00:32, Sean P. DeNigris >> <s...@clipperadams.com> >> 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.