Skip to content

Commit ed2bf53

Browse files
authored
Add CST to UTC (#135)
1 parent 64f7fc3 commit ed2bf53

7 files changed

Lines changed: 61 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1414
Example: `` [sort -u] `file.txt` <> ! ``
1515
- Functions
1616
- `chomp`
17+
- `cstToUtc`
1718
- `fromOleDate`
1819
- `toOleDate`
1920
- `__gitCompletion`

doc/functions.inc.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,7 @@ <h1 id="functions-dates">Dates <a class="section-link" href="#functions-dates" a
302302
<tr> <td><code>fromOleDate</code></td> <td>Create a date from an OLE Automation date float. This is equivalent to Excel dates (<a href="https://learn.microsoft.com/en-us/troubleshoot/microsoft-365-apps/excel/wrongly-assumes-1900-is-leap-year">Less some early time bugs</a>).</td> <td><code>(<span class="sig-type sig-type-numeric">numeric</span> -- <span class="sig-type sig-type-date">date</span>)</code></td> </tr>
303303
<tr> <td><code>addDays</code></td> <td>Add days to a date.</td> <td><code>(<span class="sig-type sig-type-date">date</span> <span class="sig-type sig-type-numeric">numeric</span> -- <span class="sig-type sig-type-date">date</span>)</code></td> </tr>
304304
<tr> <td><code>utcToCst</code></td> <td>Convert a UTC datetime to US Central Time.</td> <td><code>(<span class="sig-type sig-type-date">date</span> -- <span class="sig-type sig-type-date">date</span>)</code></td> </tr>
305+
<tr> <td><code>cstToUtc</code></td> <td>Convert a US Central Time datetime to UTC.</td> <td><code>(<span class="sig-type sig-type-date">date</span> -- <span class="sig-type sig-type-date">date</span>)</code></td> </tr>
305306
</tbody>
306307
</table>
307308

doc/mshell.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,7 @@ Metadata values must be static: strings (single or double quoted), integers, flo
380380
- `fromOleDate`: Convert an OLE Automation date float to a date `(numeric -- date)`
381381
- `addDays`: Add days to date `(date numeric -- date)`
382382
- `utcToCst`: Convert a UTC datetime to US Central Time `(date -- date)`
383+
- `cstToUtc`: Convert a US Central Time datetime to UTC `(date -- date)`
383384

384385
## Regular Expression Functions
385386

mshell/BuiltInList.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ var BuiltInList = map[string]struct{}{
2121
"ceil": {},
2222
"countSubStr": {},
2323
"cp": {},
24+
"cstToUtc": {},
2425
"date": {},
2526
"dateFmt": {},
2627
"day": {},

mshell/Evaluator.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3089,6 +3089,36 @@ MainLoop:
30893089
dateTimeObj.Time = dateTimeObj.Time.In(cstLocation)
30903090
dateTimeObj.OriginalString = ""
30913091
stack.Push(dateTimeObj)
3092+
} else if t.Lexeme == "cstToUtc" {
3093+
obj1, err := stack.Pop()
3094+
if err != nil {
3095+
return state.FailWithMessage(fmt.Sprintf("%d:%d: Cannot do 'toUtc' operation on an empty stack.\n", t.Line, t.Column))
3096+
}
3097+
3098+
// Convert the datetime to UTC from assumed CST
3099+
dateTimeObj, ok := obj1.(*MShellDateTime)
3100+
if !ok {
3101+
return state.FailWithMessage(fmt.Sprintf("%d:%d: Cannot convert a %s to UTC.\n", t.Line, t.Column, obj1.TypeName()))
3102+
}
3103+
3104+
cstLocation, err := time.LoadLocation("America/Chicago")
3105+
if err != nil {
3106+
return state.FailWithMessage(fmt.Sprintf("%d:%d: Error loading CST location: %s\n", t.Line, t.Column, err.Error()))
3107+
}
3108+
3109+
cstTime := time.Date(
3110+
dateTimeObj.Time.Year(),
3111+
dateTimeObj.Time.Month(),
3112+
dateTimeObj.Time.Day(),
3113+
dateTimeObj.Time.Hour(),
3114+
dateTimeObj.Time.Minute(),
3115+
dateTimeObj.Time.Second(),
3116+
dateTimeObj.Time.Nanosecond(),
3117+
cstLocation,
3118+
)
3119+
dateTimeObj.Time = cstTime.In(time.UTC)
3120+
dateTimeObj.OriginalString = ""
3121+
stack.Push(dateTimeObj)
30923122
} else if t.Lexeme == "floor" {
30933123
// Round a number down to the nearest integer
30943124
obj1, err := stack.Pop()

tests/tz.msh

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,17 @@
11
2025-05-29T16:00 utcToCst str wl
22
2025-01-02T16:00 utcToCst str wl
3+
2025-05-29T11:00 cstToUtc str wl
4+
2025-01-02T10:00 cstToUtc str wl
5+
6+
# DST problems
7+
"Spring Forward" wl
8+
$"1 AM: {2025-03-09T01:00 cstToUtc isoDateTimeFmt}" wl
9+
$"2 AM: {2025-03-09T02:00 cstToUtc isoDateTimeFmt}" wl
10+
$"2:30 AM (doesn't actually exist): {2025-03-09T02:30 cstToUtc isoDateTimeFmt}" wl
11+
$"3 AM: {2025-03-09T03:00 cstToUtc isoDateTimeFmt}" wl
12+
13+
"Fall Back" wl
14+
$"1 AM: {2025-11-02T01:00 cstToUtc isoDateTimeFmt}" wl
15+
$"2 AM: {2025-11-02T02:00 cstToUtc isoDateTimeFmt}" wl
16+
$"2:30 AM: {2025-11-02T02:30 cstToUtc isoDateTimeFmt}" wl
17+
$"3 AM: {2025-11-02T03:00 cstToUtc isoDateTimeFmt}" wl

tests/tz.msh.stdout

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,14 @@
11
2025-05-29T11:00:00
22
2025-01-02T10:00:00
3+
2025-05-29T16:00:00
4+
2025-01-02T16:00:00
5+
Spring Forward
6+
1 AM: 2025-03-09T07:00:00
7+
2 AM: 2025-03-09T07:00:00
8+
2:30 AM (doesn't actually exist): 2025-03-09T07:30:00
9+
3 AM: 2025-03-09T08:00:00
10+
Fall Back
11+
1 AM: 2025-11-02T06:00:00
12+
2 AM: 2025-11-02T08:00:00
13+
2:30 AM: 2025-11-02T08:30:00
14+
3 AM: 2025-11-02T09:00:00

0 commit comments

Comments
 (0)