Compare commits

...

2 Commits

Author SHA1 Message Date
93518f8294 [vscode] add new prelude functions 2025-12-10 11:12:48 -08:00
1a308eadf5 [prelude] add date functions 2025-12-10 11:12:13 -08:00
5 changed files with 244 additions and 1 deletions

12
src/prelude/date.ts Normal file
View File

@ -0,0 +1,12 @@
export const date = {
now: () => Date.now(),
year: (time: number) => (new Date(time)).getFullYear(),
month: (time: number) => (new Date(time)).getMonth(),
date: (time: number) => (new Date(time)).getDate(),
hour: (time: number) => (new Date(time)).getHours(),
minute: (time: number) => (new Date(time)).getMinutes(),
second: (time: number) => (new Date(time)).getSeconds(),
ms: (time: number) => (new Date(time)).getMilliseconds(),
new: (year: number, month: number, day: number, hour = 0, minute = 0, second = 0, ms = 0) =>
new Date(year, month, day, hour, minute, second, ms).getTime()
}

View File

@ -6,6 +6,7 @@ import {
extractParamInfo, isWrapped, getOriginalFunction,
} from 'reefvm'
import { date } from './date'
import { dict } from './dict'
import { fs } from './fs'
import { json } from './json'
@ -16,6 +17,7 @@ import { str } from './str'
import { types } from './types'
export const globals: Record<string, any> = {
date,
dict,
fs,
json,

View File

@ -0,0 +1,170 @@
import { expect, describe, test } from 'bun:test'
describe('date', () => {
test('date.now returns current timestamp', () => {
expect(`date.now | number?`).toEvaluateTo(true)
expect(`(date.now) > 1577836800000`).toEvaluateTo(true)
})
test('date.new creates timestamp from components', () => {
expect(`
t = date.new 2024 0 1 12 0 0 500
[
(date.year t)
(date.month t)
(date.date t)
(date.hour t)
(date.minute t)
(date.second t)
(date.ms t)
]
`).toEvaluateTo([2024, 0, 1, 12, 0, 0, 500])
})
test('date.new with minimal arguments', () => {
expect(`
t = date.new 2024 5 15
[
(date.year t)
(date.month t)
(date.date t)
(date.hour t)
(date.minute t)
(date.second t)
(date.ms t)
]
`).toEvaluateTo([2024, 5, 15, 0, 0, 0, 0])
})
test('date.year extracts year', () => {
expect(`
t = date.new 2024 0 1
date.year t
`).toEvaluateTo(2024)
expect(`
t = date.new 1999 11 31
date.year t
`).toEvaluateTo(1999)
})
test('date.month extracts month (0-indexed)', () => {
// January = 0, December = 11
expect(`
jan = date.new 2024 0 1
dec = date.new 2024 11 31
[(date.month jan) (date.month dec)]
`).toEvaluateTo([0, 11])
})
test('date.date extracts day of month', () => {
expect(`
t = date.new 2024 5 15
date.date t
`).toEvaluateTo(15)
expect(`
date.new 2024 0 1 | date.date
`).toEvaluateTo(1)
})
test('date.hour extracts hour', () => {
expect(`
t = date.new 2024 0 1 14 30 45
date.hour t
`).toEvaluateTo(14)
expect(`
t = date.new 2024 0 1 0 0 0
date.hour t
`).toEvaluateTo(0)
})
test('date.minute extracts minute', () => {
expect(`
t = date.new 2024 0 1 14 30 45
date.minute t
`).toEvaluateTo(30)
})
test('date.second extracts second', () => {
expect(`
t = date.new 2024 0 1 14 30 45
date.second t
`).toEvaluateTo(45)
})
test('date.ms extracts milliseconds', () => {
expect(`
t = date.new 2024 0 1 14 30 45 250
date.ms t
`).toEvaluateTo(250)
})
test('round-trip: create and extract components', () => {
expect(`
t = date.new 2024 6 4 15 30 45 123
year = date.year t
month = date.month t
day = date.date t
hour = date.hour t
min = date.minute t
sec = date.second t
ms = date.ms t
[year month day hour min sec ms]
`).toEvaluateTo([2024, 6, 4, 15, 30, 45, 123])
})
test('edge cases - midnight', () => {
expect(`
t = date.new 2024 0 1 0 0 0 0
[
(date.hour t)
(date.minute t)
(date.second t)
(date.ms t)
]
`).toEvaluateTo([0, 0, 0, 0])
})
test('edge cases - end of day', () => {
expect(`
t = date.new 2024 0 1 23 59 59 999
[
(date.hour t)
(date.minute t)
(date.second t)
(date.ms t)
]
`).toEvaluateTo([23, 59, 59, 999])
})
test('edge cases - leap year', () => {
expect(`
t = date.new 2024 1 29
[
(date.year t)
(date.month t)
(date.date t)
]
`).toEvaluateTo([2024, 1, 29])
})
test('combining date functions with arithmetic', () => {
expect(`
t = date.new 2024 5 15 10 30 0
next-hour = date.new 2024 5 15 11 30 0
(date.hour next-hour) - (date.hour t)
`).toEvaluateTo(1)
})
test('using date.now in calculations', () => {
// Check that date.now is in the past compared to a future timestamp
expect(`
now = (date.now)
future = date.new 2030 0 1
future > now
`).toEvaluateTo(true)
})
})

View File

@ -8,6 +8,57 @@ export type CompletionMetadata = {
export const completions = {
modules: {
"date": {
"now": {
"params": []
},
"year": {
"params": [
"time"
]
},
"month": {
"params": [
"time"
]
},
"date": {
"params": [
"time"
]
},
"hour": {
"params": [
"time"
]
},
"minute": {
"params": [
"time"
]
},
"second": {
"params": [
"time"
]
},
"ms": {
"params": [
"time"
]
},
"new": {
"params": [
"year",
"month",
"day",
"hour",
"minute",
"second",
"ms"
]
}
},
"dict": {
"keys": {
"params": [
@ -529,7 +580,10 @@ export const completions = {
]
},
"random": {
"params": []
"params": [
"min",
"max"
]
},
"clamp": {
"params": [

View File

@ -6,7 +6,9 @@ export const PRELUDE_NAMES = [
"array?",
"at",
"bnot",
"boolean",
"boolean?",
"date",
"dec",
"describe",
"dict",
@ -24,15 +26,18 @@ export const PRELUDE_NAMES = [
"json",
"length",
"list",
"list?",
"load",
"math",
"not",
"null?",
"number",
"number?",
"range",
"ref",
"some?",
"str",
"string",
"string?",
"type",
"var",