Jump to content

Wikifunctions:Type proposals/Gregorian calendar date

From Wikifunctions

Summary

A Gregorian calendar date identifies a specific day using the Gregorian calendar system introduced in 1582. It is the most widely used calendar system today.

The Type is proleptic, i.e. it is also calculated backwards before its introduction. There is no year 0. Another type can be introduced that has a year 0. The Type is naïve with regards to UTC, i.e. it ignores it as it only resolves to the level of days. When we introduce Functions and Types with a higher resolution, we need to resolve possible discrepancies.

Uses

  • Why should this exist?

In order to be able to reference dates and have functions that work with dates.

  • What kinds of functions would be created using this?
    • How old was a person when they died?
    • How many days have passed between two days
    • What day of the week was a certain day (requires days of the week as a type)
    • What is this date in another calendar? (requires the other calendar)
    • What is the Julian number of a given date?
    • When is Easter Sunday in a given year? (one of the main use cases for introducing the calendar)
  • What standard concepts, if any, does this align with?

The Gregorian calendar date is widely used. It was introduced through the Papal bull Inter gravissimas.

Structure

A Gregorian calendar date has two keys:

  1. K1 of Type Gregorian year
  2. K2 of Type Roman day of the year

Example values

Value for October 27, 2014:

{
  "type": "Gregorian calendar date",
  “year”: {
    type”: “Gregorian year”,
    “era”: “CE”,
    “year”: {
      type”: “Natural number”,
      “value”: 2014
    }
  },
  "day of the year": {
    type”: “Day of the Roman year”,
    “month”: “October”,
    “day”: {
      type”: “Natural number”,
      “value”: 27
    }
  }
}
{
  "Z1K1": "Znnn",
  “ZnnnK1: {
    “Z1K1: “Zppp”,
    “ZpppK1: “Zqqq”,
    “ZpppK2: {
      “Z1K1: “Z13518,
      “Z13518K1: 2014
    }
  },
  "ZnnnK2": {
    “Z1K1: “Zmmm”,
    “ZmmmK1: “Z16110,
    “ZmmmK2: {
      “Z1K1: “Z13518,
      “Z13518K1: 27
    }
  }
}

Validator

The validator ensures that:

  • February 29 only appears in leap years
  • Further validation will be performed by the subtypes.

Identity

Two dates are the same if their day of the year and their year are the same.

Converting to code

Python

In Python, the datetime.date Class only supports date four digit years in the common era, which is why we cannot use it. We convert the Gregorian calendar into a dictionary with the following structure (for the above example date):

{
  K1: True,
  K2: 2014,
  K3: 10,
  K4: 27
}

We also take such a dictionary back to convert it into a Gregorian calendar date object.

If a developer wants use the built-in datetime.date class (for the values that are covered, i.e. between January 1st 1 and December 31st 9999) in native code, a value x can be further converted like this:

import datetime d = datetime.date(x[‘K2’], x[‘K3’], x[‘K4’])

JavaScript

The language standard Date object has an impressive range, covering more than a quarter million years into the future and the past (to be exact, from 20 April 271821 BCE to 13 September 275760 CE). Nevertheless, in order to cover the unlimited range of the Wikifunctions type, we will use the following object to convert to:

{
  K1: true,
  K2: 2014,
  K3: 9,
  K4: 27
}

Note that as with Gregorian calendar months, months are started to be counted with 0, i.e. October is 9, not 10.

We also take such an object back to convert it into a Gregorian calendar date object.

If a developer wants to use the built-in Date type, a value x can be further converted like this:

d = new Date(x.K1 ? x.K2 : -x.K2, x.K3, x.K4).setFullYear(x.K1 ? x.K2 : -x.K2)

Renderer

Renderers depend on the language. We will start with a general renderer outputting an ISO string as the default behaviour, i.e. “2014-10-27 CE”, but we will have a configuration that can be adjusted for a given language, e.g. "27 October 2014" or "le 27 octobre 2014 AD".

Parsers

Parsers depend on the language. We will start with a general parser that can take an ISO string as the default behaviour, but we will have a configuration that can be adjusted for a given language.

Alternatives

  1. We could use different calendars for dates. And we certainly should! This is just to support a first calendar. Proposals for other calendars are welcome.
  2. We could follow ISO 8601 and have a year 0. But this would be inconsistent with most usages on Wikipedia. The suggestion is that we should have an ISO 8601 compatible calendar date as its own Type.
  3. The Type could be non-proleptic, i.e. not allow dates before its introduction (though its introduction varied by location and polity, so this becomes complicated).
  4. The Type could use both the Julian calendar before the introduction of the Gregorian calendar, and Gregorian aftwards, instead of being proleptic. Whereas such a date Type might be very interesting, as it may be the closest to what most written texts including Wikipedia and encyclopaedias are doing, it would be very difficult to implement correctly, might be confusing for users, and it would need an underlying proleptic Gregorian calendar date as a supporting Type anyway. So, we start here with the proleptic Gregorian calendar date, and allow for the development of a more complex Type later, that supports a mixed calendar model.
  5. Instead of using two keys with the new “day of the Roman year” Type and “Gregorian year” type, we could have a flatter representation with four keys, for a day, month, year, and era. Since both these subtypes seem useful in their own right, we used the more composed approach instead.
  6. some mixes between the previous and current proposal could also be possible, i.e. flatten the day of the year but not the year or the other way around.
  7. Instead of using a year and an era, we could use the Integer Type, and interpret negative numbers as being BCE. This seems more aligned with the ISO 8601 calendar though, which allows a year 0. Since we do not have a year 0, using the Integer Type could easier lead to mistakes.
  8. We could represent every day with just an Integer for the Julian day number, and make it look like a calendar day using parsers and renderers.
  9. The Type could be aware of UTC and define itself with a specific time zone in mind. There is a necessity for a naive date type, in order to express birthdays, events, etc., which often are intentionally naive with regards to a timezone (e.g. if a person is born in San Francisco at 23:30 on December 31st 2000, the person would have been born on January 1st 2001 6:30 UTC. We don’t want to record their Birthdate as January 1st 2001 instead of December 31st 2000. So we need to have Functions that assume naivety with regards to UTC.
  10. Instead of leaving unlimited time frames, we could stop at some big (but ultimately arbitrary) date, e.g. 100,000 BCE to 100,000 CE. Given the imprecision of the Gregorian calendar and the change in speed of the Earth, it is likely that the Gregorian proleptic calendar would fail outside of this time frame anyway. In addition, this would allow us to use the built-in JavaScript Date object, which could be a real advantage of this limitation. Dates outside this timeframe seem extremely rare.
  11. We could even constrain it to the space that Python covers (from 1CE to 9999 CE), but that seems too limiting

Comments