treasure-data / digdag

Workload Automation System
https://www.digdag.io/
Apache License 2.0
1.3k stars 221 forks source link

strftime with variable #215

Closed frsyuki closed 7 years ago

frsyuki commented 8 years ago

Formatting timestamp is one of the common use cases of ${...} expression. Vanilla JavaScript doesn't have good support for it. Having a strftime library such as https://github.com/samsonjs/strftime as a built-in library should be useful.

Discussions are:

uu59 commented 8 years ago

👍 for having it.

FWIW, let me share my case. I need to calculate "N days ago from session_time (not last_session_time)" and format it as '%Y-%m-%d' in a workflow. I did it by ${(d=new Date((session_time - (86400 * N)) * 1000) && [d.getFullYear(), ('0' + (d.getMonth()+1)).slice(-2), ('0' + d.getDate()).slice(-2)].join('-')}. It worked but it has 4 complexity:

Other popular time library moment.js can do converting and avoid assigning variable. Above one liner can be rewritten with moment.js as ${moment(session_time * 1000).add(-N, 'days').format('YYYY-MM-DD')}. It's much simpler. Probably typical user (including me) prefer strftime for formatting, but moment.js can do more work.

westwick commented 8 years ago

:+1: would also like something like this

frsyuki commented 7 years ago

I checked several libraries:

I first thought that simple strftime is the best. However, I found that it can't cover following common operations well:

On the other hand, Moment.JS seems quite feature complete:

$ jirb 
> js = Java::jdk.nashorn.api.scripting.NashornScriptEngineFactory.new.getScriptEngine("--no-java", "--no-syntax-extensions", "-timezone=Asia/Tokyo")
> js.eval(File.read('moment.js')
> js.eval(%{moment("2016-09-27T00:00:00Z").format()})
=> "2016-09-27T09:00:00+09:00"
> js.eval(%{moment("2016-09-27T00:00:00Z").format("YYYY-MM-DD HH:mm:ss Z")})
=> "2016-09-27 09:00:00 +09:00"
> js.eval(%{moment("2016-09-27T00:00:00Z").utc().format("YYYY-MM-DD HH:mm:ss Z")})
=> "2016-09-27 00:00:00 +00:00"
> js.eval(%{moment("2016-09-27T00:00:00Z").utc().add(1, 'hours').format("YYYY-MM-DD HH:mm:ss Z")})
=> "2016-09-27 01:00:00 +00:00"

session_time variable is ISO time format. Thus following code should work in digdag, for example:

echo>: ${moment(session_time).add(1, 'days').format("YYYY-MM-DD HH:00:00")}

@danielnorberg @komamitsu I think bundling Moment.js makes sense. Do you have any comments?

danielnorberg commented 7 years ago

Moment is pretty nice. We're using it in the console.