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 3 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
10 changes: 10 additions & 0 deletions src/Std/Time.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/-
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.DateTime
import Std.Time.Zoned
import Std.Time.Format
380 changes: 380 additions & 0 deletions src/Std/Time/Bounded.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,380 @@
/-
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 Init.Data.Int
import Std.Time.LessEq

namespace Std
namespace Time
algebraic-dev marked this conversation as resolved.
Show resolved Hide resolved

set_option linter.all true in

/--
A `Bounded` is represented by an `Int` that is contrained by a lower and higher bounded using some
algebraic-dev marked this conversation as resolved.
Show resolved Hide resolved
relation `rel`. It includes all the integers that `rel lo val ∧ rel val hi`.
-/
def Bounded (rel : Int → Int → Prop) (lo : Int) (hi : Int) := { val : Int // rel lo val ∧ rel val hi}

namespace Bounded

@[always_inline]
instance : LE (Bounded rel n m) where
le l r := l.val ≤ r.val

@[always_inline]
instance : LT (Bounded rel n m) where
lt l r := l.val < r.val

@[always_inline]
instance : Repr (Bounded rel m n) where
reprPrec n := reprPrec n.val

@[always_inline]
instance : BEq (Bounded rel n m) where
beq x y := (x.val = y.val)

@[always_inline]
instance {x y : Bounded rel a b} : Decidable (x ≤ y) :=
dite (x.val ≤ y.val) isTrue isFalse

/--
A `Bounded` integer that the relation used is the the less-equal relation so, it includes all
integers that `lo ≤ val ≤ hi`.
-/
abbrev LE := @Bounded LE.le

instance [Le lo n] [Le n hi] : OfNat (Bounded.LE lo hi) n where
ofNat := ⟨n, And.intro (Int.ofNat_le.mpr Le.p) (Int.ofNat_le.mpr Le.p)⟩

instance [Le lo hi] : Inhabited (Bounded.LE lo hi) where
default := ⟨lo, And.intro (Int.le_refl lo) (Int.ofNat_le.mpr Le.p)⟩

/--
A `Bounded` integer that the relation used is the the less-than relation so, it includes all
integers that `lo < val < hi`.
-/
abbrev LT := @Bounded LT.lt

/--
Creates a new `Bounded` Integer.
-/
@[inline]
def mk {rel : Int → Int → Prop} (val : Int) (proof : rel lo val ∧ rel val hi) : @Bounded rel lo hi :=
⟨val, proof⟩

namespace LE

/--
Creates a new `Bounded` integer that the relation is less-equal.
-/
@[inline]
def mk (val : Int) (proof : lo ≤ val ∧ val ≤ hi) : Bounded.LE lo hi :=
⟨val, proof⟩

/--
Creates a new `Bounded` integer.
-/
@[inline]
def ofInt { lo hi : Int } (val : Int) : Option (Bounded.LE lo hi) :=
if h : lo ≤ val ∧ val ≤ hi
then some ⟨val, h⟩
else none

/--
Convert a `Nat` to a `Bounded.LE`.
-/
@[inline]
def ofNat (val : Nat) (h : val ≤ hi) : Bounded.LE 0 hi :=
Bounded.mk val (And.intro (Int.ofNat_zero_le val) (Int.ofNat_le.mpr h))

/--
Convert a `Nat` to a `Bounded.LE` if it checks.
-/
@[inline]
def ofNat? { hi : Nat } (val : Nat) : Option (Bounded.LE 0 hi) :=
if h : val ≤ hi then
ofNat val h
else
none

/--
Convert a `Nat` to a `Bounded.LE` using the lower boundary too.
-/
@[inline]
def ofNat' (val : Nat) (h : lo ≤ val ∧ val ≤ hi) : Bounded.LE lo hi :=
Bounded.mk val (And.intro (Int.ofNat_le.mpr h.left) (Int.ofNat_le.mpr h.right))

/--
Convert a `Nat` to a `Bounded.LE` using the lower boundary too.
-/
@[inline]
def force (val : Int) (h : lo ≤ hi) : Bounded.LE lo hi :=
if h₀ : lo ≤ val then
if h₁ : val ≤ hi
then ⟨val, And.intro h₀ h₁⟩
else ⟨hi, And.intro h (Int.le_refl hi)⟩
else ⟨lo, And.intro (Int.le_refl lo) h⟩

/--
Convert a `Nat` to a `Bounded.LE` using the lower boundary too.
-/
@[inline]
def force! [Le lo hi] (val : Int) : Bounded.LE lo hi :=
if h₀ : lo ≤ val then
if h₁ : val ≤ hi
then ⟨val, And.intro h₀ h₁⟩
else panic! "greater than hi"
else panic! "lower than lo"

/--
Convert a `Bounded.LE` to a Nat.
-/
@[inline]
def toNat (n : Bounded.LE lo hi) : Nat :=
n.val.toNat

/--
Convert a `Bounded.LE` to a Nat.
-/
@[inline]
def toNat' (n : Bounded.LE lo hi) (h : lo ≥ 0) : Nat :=
let h₁ := (Int.le_trans h n.property.left)
match n.val, h₁ with
| .ofNat n, _ => n
| .negSucc _, h => nomatch h

/--
Convert a `Bounded.LE` to an Int.
-/
@[inline]
def toInt (n : Bounded.LE lo hi) : Int :=
n.val

/--
Convert a `Bounded.LE` to a `Fin`.
-/
@[inline]
def toFin (n : Bounded.LE lo hi) (h₀ : 0 ≤ lo) (h₁ : lo < hi) : Fin (hi + 1).toNat := by
let h := n.property.right
let h₁ := Int.le_trans h₀ n.property.left
refine ⟨n.val.toNat, (Int.toNat_lt h₁).mpr ?_⟩
rw [Int.toNat_of_nonneg (by omega)]
exact Int.lt_add_one_of_le h

/--
Convert a `Fin` to a `Bounded.LE`.
-/
@[inline]
def ofFin (fin : Fin (Nat.succ hi)) : Bounded.LE 0 hi :=
ofNat fin.val (Nat.le_of_lt_succ fin.isLt)

/--
Convert a `Fin` to a `Bounded.LE`.
-/
@[inline]
def ofFin' {lo : Nat} (fin : Fin (Nat.succ hi)) (h : lo ≤ hi) : Bounded.LE lo hi :=
if h₁ : fin.val ≥ lo
then ofNat' fin.val (And.intro h₁ ((Nat.le_of_lt_succ fin.isLt)))
else ofNat' lo (And.intro (Nat.le_refl lo) h)

/--
Creates a new `Bounded.LE` using a the modulus of a number.
-/
@[inline]
def byEmod (b : Int) (i : Int) (hi : i > 0) : Bounded.LE 0 (i - 1) := by
refine ⟨b % i, And.intro ?_ ?_⟩
· apply Int.emod_nonneg b
intro a
simp_all [Int.lt_irrefl]
· apply Int.le_of_lt_add_one
simp [Int.add_sub_assoc]
exact Int.emod_lt_of_pos b hi

/--
Creates a new `Bounded.LE` using a the Truncating modulus of a number.
-/
@[inline]
def byMod (b : Int) (i : Int) (hi : 0 < i) : Bounded.LE (- (i - 1)) (i - 1) := by
refine ⟨b.mod i, And.intro ?_ ?_⟩
· simp [Int.mod]
split <;> try contradiction
next m n =>
let h := Int.emod_nonneg (a := m) (b := n) (Int.ne_of_gt hi)
apply (Int.le_trans · h)
apply Int.le_of_neg_le_neg
simp_all
exact (Int.le_sub_one_of_lt hi)
next m n =>
apply Int.neg_le_neg
have h := Int.mod_lt_of_pos (m + 1) hi
exact Int.le_sub_one_of_lt h
· exact Int.le_sub_one_of_lt (Int.mod_lt_of_pos b hi)

/--
Adjust the bounds of a `Bounded` by setting the lower bound to zero and the maximum value to (m - n).
-/
@[inline]
def truncate (bounded : Bounded.LE n m) : Bounded.LE 0 (m - n) := by
let ⟨left, right⟩ := bounded.property
refine ⟨bounded.val - n, And.intro ?_ ?_⟩
all_goals omega

/--
Adjust the bounds of a `Bounded` by changing the higher bound if another value `j` satisfies the same
constraint.
-/
@[inline]
def truncateTop (bounded : Bounded.LE n m) (h : bounded.val ≤ j) : Bounded.LE n j := by
refine ⟨bounded.val, And.intro ?_ ?_⟩
· exact bounded.property.left
· exact h

/--
Adjust the bounds of a `Bounded` by changing the lower bound if another value `j` satisfies the same
constraint.
-/
@[inline]
def truncateBottom (bounded : Bounded.LE n m) (h : bounded.val ≥ j) : Bounded.LE j m := by
refine ⟨bounded.val, And.intro ?_ ?_⟩
· exact h
· exact bounded.property.right

/--
Adjust the bounds of a `Bounded` by adding a constant value to both the lower and upper bounds.
-/
@[inline]
def neg (bounded : Bounded.LE n m) : Bounded.LE (-m) (-n) := by
refine ⟨-bounded.val, And.intro ?_ ?_⟩
· exact Int.neg_le_neg bounded.property.right
· exact Int.neg_le_neg bounded.property.left

/--
Adjust the bounds of a `Bounded` by adding a constant value to both the lower and upper bounds.
-/
@[inline]
def add (bounded : Bounded.LE n m) (num : Int) : Bounded.LE (n + num) (m + num) := by
refine ⟨bounded.val + num, And.intro ?_ ?_⟩
all_goals apply (Int.add_le_add · (Int.le_refl num))
· exact bounded.property.left
· exact bounded.property.right

/--
Adjust the bounds of a `Bounded` by adding a constant value to the upper bounds.
-/
@[inline]
def addTop (bounded : Bounded.LE n m) (num : Nat) : Bounded.LE n (m + num) := by
refine ⟨bounded.val + num, And.intro ?_ ?_⟩
· let h := Int.add_le_add bounded.property.left (Int.ofNat_zero_le num)
simp at h
exact h
· exact Int.add_le_add bounded.property.right (Int.le_refl num)

/--
Adjust the bounds of a `Bounded` by adding a constant value to the lower bounds.
-/
@[inline]
def subBottom (bounded : Bounded.LE n m) (num : Nat) : Bounded.LE (n - num) m := by
refine ⟨bounded.val - num, And.intro ?_ ?_⟩
· exact Int.add_le_add bounded.property.left (Int.le_refl (-num))
· let h := Int.sub_le_sub bounded.property.right (Int.ofNat_zero_le num)
simp at h
exact h

/--
Adds two `Bounded` and adjust the boundaries.
-/
@[inline]
def addBounds (bounded : Bounded.LE n m) (bounded₂ : Bounded.LE n m) : Bounded.LE (n + n) (m + m) := by
refine ⟨bounded.val + bounded₂.val, And.intro ?_ ?_⟩
· exact Int.add_le_add bounded.property.left bounded₂.property.left
· exact Int.add_le_add bounded.property.right bounded₂.property.right

/--
Adjust the bounds of a `Bounded` by subtracting a constant value to both the lower and upper bounds.
-/
@[inline]
def sub (bounded : Bounded.LE n m) (num : Int) : Bounded.LE (n - num) (m - num) :=
add bounded (-num)

/--
Adds two `Bounded` and adjust the boundaries.
-/
@[inline]
def subBounds (bounded : Bounded.LE n m) (bounded₂ : Bounded.LE n m) : Bounded.LE (n - m) (m - n) := by
refine ⟨bounded.val - bounded₂.val, And.intro ?_ ?_⟩
· exact Int.sub_le_sub bounded.property.left bounded₂.property.right
· exact Int.sub_le_sub bounded.property.right bounded₂.property.left

/--
Adjust the bounds of a `Bounded` by applying the emod operation constraining the lower bound to 0 and
the upper bound to the value.
-/
@[inline]
def emod (bounded : Bounded.LE n num) (num : Int) (hi : 0 < num) : Bounded.LE 0 (num - 1) :=
byEmod bounded.val num hi

/--
Adjust the bounds of a `Bounded` by applying the mod operation.
-/
@[inline]
def mod (bounded : Bounded.LE n num) (num : Int) (hi : 0 < num) : Bounded.LE (- (num - 1)) (num - 1) :=
byMod bounded.val num hi

/--
Adjust the bounds of a `Bounded` by applying the multiplication operation with a positive number.
-/
@[inline]
def mul_pos (bounded : Bounded.LE n m) (num : Int) (h : num ≥ 0) : Bounded.LE (n * num) (m * num) := by
refine ⟨bounded.val * num, And.intro ?_ ?_⟩
· exact Int.mul_le_mul_of_nonneg_right bounded.property.left h
· exact Int.mul_le_mul_of_nonneg_right bounded.property.right h

/--
Adjust the bounds of a `Bounded` by applying the multiplication operation with a positive number.
-/
@[inline]
def mul_neg (bounded : Bounded.LE n m) (num : Int) (h : num ≤ 0) : Bounded.LE (m * num) (n * num) := by
refine ⟨bounded.val * num, And.intro ?_ ?_⟩
· exact Int.mul_le_mul_of_nonpos_right bounded.property.right h
· exact Int.mul_le_mul_of_nonpos_right bounded.property.left h
/--
Adjust the bounds of a `Bounded` by applying the div operation.
-/
@[inline]
def div (bounded : Bounded.LE n m) (num : Int) (h : num > 0) : Bounded.LE (n / num) (m / num) := by
let ⟨left, right⟩ := bounded.property
refine ⟨bounded.val / num, And.intro ?_ ?_⟩
apply Int.ediv_le_ediv
· exact h
· exact left
· apply Int.ediv_le_ediv
· exact h
· exact right

/--
Expand the bottom of the bounded to a number `nhi` is `hi` is less or equal to the previous higher bound.
-/
@[inline]
def expandTop (bounded : Bounded.LE lo hi) (h : hi ≤ nhi) : Bounded.LE lo nhi :=
⟨bounded.val, And.intro bounded.property.left (Int.le_trans bounded.property.right h)⟩

/--
Expand the bottom of the bounded to a number `nlo` if `lo` is greater or equal to the previous lower bound.
-/
@[inline]
def expandBottom (bounded : Bounded.LE lo hi) (h : nlo ≤ lo) : Bounded.LE nlo hi :=
⟨bounded.val, And.intro (Int.le_trans h bounded.property.left) bounded.property.right⟩

/--
Adds one to the value of the bounded if the value is less than the higher bound of the bounded number.
-/
@[inline]
def succ (bounded : Bounded.LE lo hi) (h : bounded.val < hi) : Bounded.LE lo hi :=
let left := bounded.property.left
⟨bounded.val + 1, And.intro (by omega) (by omega)⟩

end LE
end Bounded
Loading
Loading