0

I want to find solution to the next problem, but I need to write EBNF of time in two formats, year-month-day and month-day-year to see the differences:

Identify one advantage of writing dates as a structured-integer in the form: year, month, day (1954-02-10) instead of in the normal order (02-10-1954).

Format: year-month-day. Here is what I came up with:

<NonZeroDigit> ::= ("1" | "2" | ... | "9")
<Month> ::= ( "0" <NonZeroDigit> ) | ( "1" ( "0" | "1" | "2" ) ) 
<Day> ::= ( "0" <NonZeroDigit> ) | ( ("1" | "2") <NonZeroDigit> ) | ("3" ( "0" | "1" ) )
<Year> ::= ( "000" <NonZeroDigit> ) | 
            ( "00" <NonZeroDigit> <NonZeroDigit> ) | 
            ( "0" <NonZeroDigit> <NonZeroDigit> <NonZeroDigit> ) | 
            ( "1"  <NonZeroDigit> <NonZeroDigit> <NonZeroDigit>) |
            ( "20" <NonZeroDigit> <NonZeroDigit> ) )

The year goes to 2099 which I guess its ok and these rules work but is there a better way to write EBNF of the time? Do I miss something?

Vlad
  • 2,739
  • 7
  • 49
  • 100
  • 2
    Is it OK for you to allow a date such as February 31st? If so, you can simplify if you define ::= | "0" and just let year have four Digits. You will go up to the year 9999. Else you will have to discern between months having 28,30,31 days. What about leap years with Feb having 29 days? – Roland Mar 13 '16 at 14:49
  • Yes, forgot those things haha. Will check again. But I am on the right track? – Vlad Mar 13 '16 at 14:59
  • 1
    Yes. It is all about getting the right groupings and not repeating yourself too much. And another thing: you might need to include the dash "-" when you put it all together to define – Roland Mar 13 '16 at 15:07

1 Answers1

0

So the solution I came up with is this:

<FebruaryNum> ::= "02"
<Dash> ::= "-"
<NonLeapDigit> ::= "1" | "2" | "3" | "5" | "6" | "7"
<LeapDigit> ::= "4" | "8"
<NonZeroOrNineDigit> ::= <NonLeapDigit> | <LeapDigit>
<Digit> ::= "0" | <NonZeroOrNineDigit> | "9"
<ThreeDigits> ::= <Digit> <Digit> <Digit>
<DaysFebNonLeap> ::= ( "0" <Digit> ) | ( ("1" | "2" ) ( <NonZeroOrNineDigit> | "0")
<DaysFebLeap> ::= <DaysFebNonLeap> | "29"
<Days30> ::= <DaysFebLeap> | "30"
<Days31> ::= <Days30> | "31" 
<LeapYear> ::= <ThreeDigits> ( <LeapDigit> | "0" )
<NonLeapYear> ::= <ThreeDigits> ( "0" | <NonLeapDigit> | "9" )
<Month31Days> ::= ( ( "0" ( "1" | "3" | "5" | "7" | "8") ) | ( "1" ( "0" | "2" ) ) ) <Dash> <Days31>
<Month30Days> ::= ( ( "0" ( "4" | "6" | "9" ) ) | "11" ) <Dash> <Days30> 
<FebruaryLeap> ::= <FebruaryNum> <Dash> <DaysFebLeap>
<FebruaryNonLeap> ::= <FebruaryNum> <Dash> <DaysFebNonLeap>

<DateYearMonthDay> ::= ( <LeapYear> <Dash> ( <FebruaryLeap> | <Month30Days> | <Month31Days> ) ) | 
                        ( <NonLeapYear> <Dash> ( <FebruaryNonLeap> | <Month30Days> | <Month31Days> ))

And the advantage you get when writing year-month-day instead of day-month-year or month-day-year is, day is dependent on the month and month is dependent on the year so it is easier to program automata that can print date in format year-month-day.

Vlad
  • 2,739
  • 7
  • 49
  • 100