Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add date and time functionality #4904

Open
wants to merge 76 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 66 commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
9c1be6c
feat: add datetime library
algebraic-dev Aug 2, 2024
856f569
chore: remove useless piece of code
algebraic-dev Aug 2, 2024
a9bf653
feat: format and moved the folder to the right place
algebraic-dev Aug 5, 2024
36108dd
Merge branch 'leanprover:master' into master
algebraic-dev Aug 7, 2024
a2e3a4e
feat: api docs, parser changes, notation, renames and improve documen…
algebraic-dev Aug 7, 2024
21563e8
refactor: rename some functions
algebraic-dev Aug 7, 2024
e0da8a6
feat: zone rules
algebraic-dev Aug 9, 2024
5e269e2
fix: wrong import
algebraic-dev Aug 9, 2024
8d0f196
feat: add io functions for timestamp and instant
algebraic-dev Aug 9, 2024
2c8ef66
feat: removes LE, adds a bunch of add and sub functions, move interva…
algebraic-dev Aug 14, 2024
858415c
chore: fix comment
algebraic-dev Aug 14, 2024
882fb0e
style: fix comment whitespaces
algebraic-dev Aug 14, 2024
5c01abe
style: fix whitespaces between declarations
algebraic-dev Aug 14, 2024
cf9b567
style: fix some comments and add prelude on the top
algebraic-dev Aug 14, 2024
5d058ad
feat: add parsing functions
algebraic-dev Aug 14, 2024
4e3b9b1
style: rename function and whitespace
algebraic-dev Aug 14, 2024
abfd3be
style: add prelude import
algebraic-dev Aug 14, 2024
bd236c1
style: reorder imports and comments
algebraic-dev Aug 15, 2024
4032ad2
feat: isDST flag for timezones
algebraic-dev Aug 15, 2024
2376e62
feat: a lot of conversion functions
algebraic-dev Aug 15, 2024
d53c100
style: fix some comments
algebraic-dev Aug 16, 2024
f724551
feat: add some functions and tests
algebraic-dev Aug 16, 2024
248ed5e
feat: add missing functions
algebraic-dev Aug 16, 2024
58a446b
fix: wrong comments
algebraic-dev Aug 16, 2024
c480249
fix: some small fixes and add things to duration
algebraic-dev Aug 19, 2024
9abb7b6
fix: small bugs and tests
algebraic-dev Aug 20, 2024
e9be735
fix: a bunch of problems and added tests
algebraic-dev Aug 20, 2024
89cfd2c
refactor: some structures and add test
algebraic-dev Aug 21, 2024
b193aac
feat: change some native functions
algebraic-dev Aug 23, 2024
a48f4ff
fix: bug with timezone change in localdatetime
algebraic-dev Aug 23, 2024
7b5754e
feat: add format functions
algebraic-dev Aug 23, 2024
842fb3b
feat: add a bunch of arithmetic functions
algebraic-dev Aug 23, 2024
3b83c6c
feat: add more sub and add functions
algebraic-dev Aug 23, 2024
d1bef18
test: add test for time operations
algebraic-dev Aug 23, 2024
ee0578f
chore: remove useless comments
algebraic-dev Aug 23, 2024
ab1d8cd
feat: changed function names and added ofSeconds and ofNanoseconds to…
algebraic-dev Aug 23, 2024
cafb98f
chore: reverting the branch :/
algebraic-dev Aug 26, 2024
c82e856
chore: reverting the branch :/
algebraic-dev Aug 26, 2024
073409d
Merge branch 'master' of github.com:leanprover/lean4
algebraic-dev Aug 26, 2024
091a969
refactor: changes Rat to Std.Internal and Parsec imports that was broken
algebraic-dev Aug 26, 2024
6c3cec4
refactor: changed names add some utilitary functions
algebraic-dev Aug 28, 2024
c30e4a1
feat: add conversion functions
algebraic-dev Aug 28, 2024
ada5670
fix: problems with since functions
algebraic-dev Aug 28, 2024
408fc65
tests: add more tests
algebraic-dev Aug 28, 2024
3f9899b
feat: add more conversion functions for timestamp
algebraic-dev Aug 28, 2024
ebadb4f
feat: remove notation import
algebraic-dev Aug 28, 2024
8e0794f
fix: problems with tests and function names
algebraic-dev Aug 28, 2024
0f755ec
fix: tests using Rat
algebraic-dev Aug 28, 2024
751b852
fix: update src/Std/Time/Duration.lean
algebraic-dev Aug 28, 2024
ec3968c
fix: update src/Std/Time.lean message
algebraic-dev Aug 28, 2024
86fec58
style: remove whitspace.
algebraic-dev Aug 28, 2024
3dabdcd
refactor: change Timestamp to depend on Duration
algebraic-dev Aug 28, 2024
1cccd65
refactor: fix some function names
algebraic-dev Aug 28, 2024
b1da2da
feat: add some class operations that result in durations
algebraic-dev Aug 28, 2024
7bc1a7c
feat: adjust pretty printing and notation for dates
algebraic-dev Aug 28, 2024
fe48007
refactor: modified each formatter to use the a default format that ca…
algebraic-dev Aug 28, 2024
f85c0cf
feat: add a bunch of conversion functions and fixes
algebraic-dev Aug 29, 2024
79c90c9
refactor: change notation syntax, add error handling for the get_time…
algebraic-dev Aug 30, 2024
b32c8a6
fix: avoid creating new tokens
algebraic-dev Aug 30, 2024
60f5b92
refactor: rename err to tm_ptr in io.cpp
algebraic-dev Sep 2, 2024
27e9893
refactor: fix names of things that were changed with search-and-repla…
algebraic-dev Sep 2, 2024
8d23eb0
fix: name of the localPath that is wrong
algebraic-dev Sep 2, 2024
b84a0e2
style: changes all the lambdas for fun
algebraic-dev Sep 2, 2024
3031f26
fix: wrong name of function
algebraic-dev Sep 2, 2024
16b4a72
fix: function names, ofOrdinal and others
algebraic-dev Sep 2, 2024
c772bd7
Merge branch 'master' of github.com:algebraic-dev/lean4
algebraic-dev Sep 2, 2024
cab1802
reafactor: notation and format
algebraic-dev Sep 20, 2024
d152573
fix: set functions and hour marker
algebraic-dev Sep 20, 2024
c6659e9
Merge branch 'master' of github.com:leanprover/lean4
algebraic-dev Sep 20, 2024
594aa87
fix: deprecations
algebraic-dev Sep 20, 2024
5367936
feat: remove lean parser from notation
algebraic-dev Sep 20, 2024
18feda1
fix: rename div to tdiv
algebraic-dev Sep 20, 2024
b213fc7
fix: tests
algebraic-dev Sep 20, 2024
9e74aac
fix: a bunch of comments and inlines
algebraic-dev Sep 26, 2024
fb8f037
fix: grammar correction
algebraic-dev Sep 30, 2024
d353fa6
feat: add leap second parser
algebraic-dev Oct 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion src/Lean/Data.lean
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,3 @@ import Lean.Data.Xml
import Lean.Data.NameTrie
import Lean.Data.RBTree
import Lean.Data.RBMap
import Lean.Data.Rat
3 changes: 2 additions & 1 deletion src/Lean/Meta/Tactic/LinearArith/Solver.lean
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ Authors: Leonardo de Moura
prelude
import Init.Data.Ord
import Init.Data.Array.DecidableEq
import Lean.Data.Rat
import Std.Internal.Rat

namespace Lean.Meta.Linear
open Std.Internal

structure Var where
id : Nat
Expand Down
1 change: 1 addition & 0 deletions src/Std.lean
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ Authors: Sebastian Ullrich
prelude
import Std.Data
import Std.Sat
import Std.Time
import Std.Tactic
import Std.Internal
6 changes: 4 additions & 2 deletions src/Lean/Data/Rat.lean → src/Std/Internal/Rat.lean
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import Init.NotationExtra
import Init.Data.ToString.Macro
import Init.Data.Int.DivMod
import Init.Data.Nat.Gcd
namespace Lean
namespace Std
namespace Internal

/-!
Rational numbers for implementing decision procedures.
Expand Down Expand Up @@ -144,4 +145,5 @@ instance : Coe Int Rat where
coe num := { num }

end Rat
end Lean
end Internal
end Std
173 changes: 173 additions & 0 deletions src/Std/Time.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
/-
algebraic-dev marked this conversation as resolved.
Show resolved Hide resolved
Copyright (c) 2024 Lean FRO, LLC. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Sofia Rodrigues
-/
import Std.Time.Time
import Std.Time.Date
import Std.Time.Zoned
import Std.Time.Format
import Std.Time.DateTime
import Std.Time.Notation
import Std.Time.Duration

namespace Std
namespace Time

/-!
# Time
algebraic-dev marked this conversation as resolved.
Show resolved Hide resolved

The Lean4 API for date, time, and duration functionalities, following the ISO8601 standards.

# Overview

This module of the standard library defines various concepts related to time, such as dates, times,
time zones and durations. These types are designed to be strongly-typed and to avoid problems with
conversion. It offers both unbounded and bounded variants to suit different use cases, like
adding days to a date or representing ordinal values.

# Date and Time Components

Date and time components are classified into different types based how you SHOULD use them. These
components are categorized as:

## Offset
algebraic-dev marked this conversation as resolved.
Show resolved Hide resolved

Offsets represent unbounded shifts in specific date or time units. They are typically used in operations
like `date.addDays` where a `Day.Offset` is the parameter. Some offsets, such as `Month.Offset`, do not
correspond directly to a specific duration in seconds, as their value depends on the context (if
the year is leap or the size of the month). Offsets with a clear correspondent to seconds can be
converted because they use an internal type called `UnitVal`.

- Types with a correspondence to seconds:
- `Day.Offset`
- `Hour.Offset`
- `WeekOfYear.Offset`
- `Millisecond.Offset`
- `Nanosecond.Offset`
- `Second.Offset`

- Types without a correspondence to seconds:
- `Month.Offset`
- `Year.Offset`

## Ordinal

Ordinal types represent specific bounded values in reference to another unit, e.g., `Day.Ordinal`
represents a day in a month, ranging from 1 to 31. Some ordinal types like `Hour.Ordinal` and `Second.Ordinal`,
allow for values beyond the normal range (e.g, 24 hours and 61 seconds) to accomodate special cases
with leap seconds like `24:00:00` that is valid in ISO 8601.

- Ordinal types:
- `Day.Ordinal`: Ranges from 1 to 31.
- `Day.Ordinal.OfYear`: Ranges from 1 to (365 or 366).
- `Month.Ordinal`: Ranges from 1 to 12.
- `WeekOfYear.Ordinal`: Ranges from 1 to 53.
- `Hour.Ordinal`: Ranges from 0 to 24.
- `Millisecond.Ordinal`: Ranges from 0 to 999.
- `Minute.Ordinal`: Ranges from 0 to 59.
- `Nanosecond.Ordinal`: Ranges from 0 to 999,999,999.
- `Second.Ordinal`: Ranges from 0 to 60.
- `Weekday`: That is a inductive type with all the seven days.

## Span

Span types are used as subcomponents of other types. They represent a range of values in the limits
of the parent type, e.g, `Nanosecond.Span` ranges from -999,999,999 to 999,999,999, as 1,000,000,000
nanoseconds corresponds to one second.

- Span types:
- `Nanosecond.Span`: Ranges from -999,999,999 to 999,999,999.

# Date and Time Types

Dates and times are composed of these components. Dates are "absolute" value in contrast with Offsets
that are just shifts in dates and times. Types like `Date` are made using of components such as `Year.Offset`,
`Month.Ordinal`, and `Day.Ordinal`, with a proof of the date's validity.

## Date
These types provide precision down to the day level, useful for representing and manipulating dates.

- **`PlainDate`:** Represents a calendar date in the format `YYYY-MM-DD`.
- **`WeekDate`:** Uses the `YYYY-Www` format with week level precision.

## Time
These types offer precision down to the nanosecond level, useful for representing and manipulating time of day.

- **`PlainTime`**: Represents a time of day in the format `HH:mm:ss,sssssssss`.

## Date and time
Combines date and time into a single representation, useful for precise timestamps and scheduling.

- **`PlainDateTime`**: Represents both date and time in the format `YYYY-MM-DDTHH:mm:ss,sssssssss`.
- **`Timestamp`**: Represents a point in time with nanosecond-level precision. It starts on the UNIX
epoch and it should be used when you receive or need to send timestamps to other systems.

## Zoned date and times.
Combines date, time and time zones.

- **`DateTime`**: Represents both date and time but with a time zone in the type constructor.
- **`ZonedDateTime`**: An existential version of the `DateTime`.

## Duration
Represents spans of time and the difference between two points in time.

- **`Duration`**: Represents the time span or difference between two `Timestamp`s values with nanosecond precision.

# Formats

Format strings are used to convert between `String` representations and date/time types, e.g, `YYYY-MM-DD'T'hh:mm:ss.sssZ`.
The supported formats include:

- **Year:**
- `YYYY`: Four-digit year (e.g., 2024)
- `YY`: Two-digit year (e.g., 24 for 2024)
- **Month:**
- `MMMM`: Full month name (e.g., January, February)
- `MMM`: Abbreviated month name (e.g., Jan, Feb)
- `MM`: Two-digit month (e.g., 01 for January)
- `M`: One or two-digit month (e.g., 1 for January, 10 for October)
- **Day:**
- `DD`: Two-digit day of the month (e.g., 01, 02)
- `D`: One or two-digit day of the month (e.g., 1, 2)
- `d`: One or two-digit day of the month with space padding (e.g., " 1", "12")
- **Day of Week:**
- `EEEE`: Full name of the day of the week (e.g., Monday, Tuesday)
- `EEE`: Abbreviated day of the week (e.g., Mon, Tue)
- **Hour:**
- `hh`: Two-digit hour in 24-hour format (e.g., 13, 14)
- `h`: One or two-digit hour in 24-hour format (e.g., 1, 2)
- `HH`: Two-digit hour in 12-hour format (e.g., 01, 02)
- `H`: One or two-digit hour in 12-hour format (e.g., 1, 2)
- **AM/PM Indicator:**
- `AA`: Uppercase AM/PM (e.g., AM, PM)
- `aa`: Lowercase am/pm (e.g., am, pm)
- **Minute:**
- `mm`: Two-digit minute (e.g., 01, 02)
- `m`: One or two-digit minute (e.g., 1, 2)
- **Second:**
- `sssssssss` : Nine-digit nanosseconds (e.g., 000000009)
- `sss`: Three-digit milliseconds (e.g., 001, 202)
- `ss`: Two-digit second (e.g., 01, 02)
- `s`: One or two-digit second (e.g., 1, 2)
- **Timezone:**
- `ZZZZZ`: Full timezone offset with hours and minutes (e.g., +03:00)
- `ZZZZ`: Timezone offset without the colon (e.g., +0300)
- `ZZZ`: Like `ZZZZ`, but with "UTC" for UTC
- `Z`: Like `ZZZZZ`, but with "Z" for UTC
- `z`: Timezone name (e.g., Brasilia Standard Time)

# Macros

In order to help the user build dates easily, there are a lot of macros available for creating dates.
The `.sssssssss` can be ommited in most cases.

- **`date% YYYY-MM-DD`**: Defines a date in the `YYYY-MM-DD` format.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that it is currently not possible to parse dates with small or large years (like negative years or years which are not four digits long.

Copy link
Contributor

@eric-wieser eric-wieser Aug 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to https://www.tondering.dk/claus/cal/iso8601.php, ISO8601 says that five digit years are to be written +10000, with a leading plus

Copy link
Contributor

@hargoniX hargoniX Aug 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is date% supposed to be ISO 8601 conform? I went through the bug tracker of https://github.com/time-rs/time and https://github.com/chronotope/chrono to look for some parsing bugs etc. that might show interesting edge cases and there are tickets that contain strings date% cannot parse but their 8601 parser can parse, for example:

#eval date% 2022-07-22T12:52:50.349409+00:00 -- https://github.com/time-rs/time/issues/488
#eval date% 2023-12-11T11:31:60.000Z -- https://github.com/time-rs/time/issues/674
#eval date% 2017-06-22T13:32:16Z -- https://github.com/chronotope/chrono/issues/163

Are these in scope?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that these are not supposed to be compliant, mainly because it seems we cannot use . in our notation for parsing reasons? It might be a good idea to change the notation from separating date and time with a colon to separating them with a T instead.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also looked in ISO 8601:2004 (I haven't got hold of ISO 8601:2019 yet, but I might later), and there for the decimal separator they allow . and , and comma is preferred over period. Colon is disallowed. So one could argue that the best format would be date% YYYY-MM-DDTHH:mm:ss,sssssssss

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm having problems trying to create a syntax with noWs 'T' noWs, the quotation gets confused with something like $date:dateT$time:time. The other problem is that the sssssssss should be the fractional part, not the nanoseconds part, so if someone writes 13:12:11,1 the 1 will be understood as 0000000001 nanoseconds.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the quotation gets confused with something like $date:dateT$time:time.

$(date)T$(time) seems to work.

Copy link
Author

@algebraic-dev algebraic-dev Aug 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried using your suggestion with syntax date noWs "T" noWs time : datetime, but I'm still running into issues. specifically, when I changed this line to (datetime| $(date)T$(time)), I got an unexpected token 'T'; expected ')' error for some weird reason.

- **`date% HH:mm:ss,sssssssss`**: Defines a time in the `HH:mm:ss:sssssssss` format, including fractional seconds.
algebraic-dev marked this conversation as resolved.
Show resolved Hide resolved
- **`date% YYYY-MM-DD T HH:mm:ss,sssssssss`**: Defines a datetime in the `YYYY-MM-DD:HH:mm:ss:sssssssss` format.
- **`date% YYYY-MM-DD T HH:mm:ss,sssssssssZ`**: Defines a datetime with a timezone in the `YYYY-MM-DDTHH:mm:ss:sssssssssZ` format.
- **`time% HH:mm:ss,sssssssss`**: Defines a time in the `HH:mm:ss` format.
- **`offset% +HH:mm`**: Defines a timezone offset in the format `+HH:mm`.
- **`timezone% NAME/ID offset% +HH:mm`**: Defines a timezone with a name and an offset.
algebraic-dev marked this conversation as resolved.
Show resolved Hide resolved
- **`date-spec% "format"`**: Defines a date specification format at compile time using the provided format string.
-/
8 changes: 8 additions & 0 deletions src/Std/Time/Date.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/-
Copyright (c) 2024 Lean FRO, LLC. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Sofia Rodrigues
-/
prelude
import Std.Time.Date.Basic
import Std.Time.Date.PlainDate
7 changes: 7 additions & 0 deletions src/Std/Time/Date/Basic.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/-
Copyright (c) 2024 Lean FRO, LLC. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Sofia Rodrigues
-/
prelude
import Std.Time.Date.Unit.Basic
Loading
Loading