expr icon indicating copy to clipboard operation
expr copied to clipboard

Add timezone convert

Open lukas-vollmer opened this issue 2 years ago • 9 comments

Any plans to add the option to convert to a different timezone. I think currently you can only specify a timezone for the input as part of the date() function.

Could be an extra function or an optional parameter of the date function. date("2023-08-14T00:00:00Z").toTimezone('America/Los_Angeles')

I think it would make sense since its also part of the time package and already used to specify the input date.

lukas-vollmer avatar Jan 04 '24 15:01 lukas-vollmer

Go already have In() function https://pkg.go.dev/time#Time.In

Expr only need a way to create a Location from a string. Right now I found this way 🫣

let utc = date("2023-08-14 00:00:00", "2006-01-02 15:04:05", "UTC").Location();
now().In(utc)

antonmedv avatar Jan 04 '24 16:01 antonmedv

What about adding timezone()?

now().In(timezone('Europe/Moscow'))

antonmedv avatar Jan 04 '24 17:01 antonmedv

Hmm, since the date function also accepts the timezone as a string (date("2023-08-14 00:00:00", "2006-01-02 15:04:05", "Europe/Zurich")) it would be cleaner to don't have a separate timezone() function to convert.

now().In('Europe/Moscow') Not the biggest fan of the In() wording (could be a bit confusing for users that don't know the go time functions).

Here a couple of ideas:

now().ToTimezone('Europe/Moscow') now().Timezone('Europe/Moscow') now().Format('Jan 2006', 'Europe/Moscow') (second optional parameter of the format function)

lukas-vollmer avatar Jan 04 '24 17:01 lukas-vollmer

I do not really want to wrap time.Time package into my own. ¯\_(ツ)_/¯

antonmedv avatar Jan 04 '24 18:01 antonmedv

Do as you like :-)

lukas-vollmer avatar Jan 05 '24 09:01 lukas-vollmer

It's a little convoluted when using now() because you have to format it then re-parse it, but it's possible with #633:

❯ date(now().Format("2006-01-02T15:04:05-0700"), "2006-01-02T15:04:05-0700", "America/Los_Angeles").Format("2006-01-02T15:04:05-0700")
2024-04-24T04:37:13-0700
❯ date(now().Format("2006-01-02T15:04:05-0700"), "2006-01-02T15:04:05-0700", "Europe/Moscow").Format("2006-01-02T15:04:05-0700")
2024-04-24T14:37:25+0300

cwarden avatar Apr 24 '24 11:04 cwarden

What about adding TZ param to now()?

now("Europe/Moscow")

antonmedv avatar Apr 24 '24 17:04 antonmedv

What about adding TZ param to now()?

now("Europe/Moscow")

There's an implementation in #635.

cwarden avatar Apr 26 '24 13:04 cwarden

Another idea: lets overload in operator for timezone convert? This very clean and readable syntax:

now() in 'UTC'

And also let's add a expr.Timezone() option to configure default timezone for date() and now() functions.

expr.Compile(code, expr.Timezone("Europe/Zurich"))

antonmedv avatar Apr 26 '24 15:04 antonmedv

I've implemented a default timezone option:

program, err := expr.Compile(`now().Location().String()`, expr.Timezone("Asia/Kamchatka"))
if err != nil {
	fmt.Printf("%v", err)
	return
}

output, err := expr.Run(program, nil)
if err != nil {
	fmt.Printf("%v", err)
	return
}

fmt.Printf("%v", output)
// Output: Asia/Kamchatka

And a new builtin timezone():

now().In(timezone("Asia/Kamchatka"))

antonmedv avatar May 08 '24 07:05 antonmedv