using System; using System.Globalization; using System.Threading; using System.Threading.Tasks; using Elsa.Scripting.JavaScript.Messages; using MediatR; using NodaTime; namespace Elsa.Scripting.JavaScript.Handlers { public class DateTimeScriptEngineConfigurator : INotificationHandler { private readonly IClock clock; public DateTimeScriptEngineConfigurator(IClock clock) { this.clock = clock; } public Task Handle(EvaluatingJavaScriptExpression notification, CancellationToken cancellationToken) { var engine = notification.Engine; engine.SetValue( "instantFromDateTimeUtc", (Func) Instant.FromDateTimeUtc); engine.SetValue( "currentInstant", (Func) (() => clock.GetCurrentInstant()) ); engine.SetValue( "currentYear", (Func) (() => clock.GetCurrentInstant().InUtc().Year) ); engine.SetValue( "startOfMonth", (Func) (instant => (instant ?? clock.GetCurrentInstant()).InUtc().LocalDateTime.With(DateAdjusters.StartOfMonth).Date) ); engine.SetValue( "endOfMonth", (Func) (instant => (instant ?? clock.GetCurrentInstant()).InUtc().LocalDateTime.With(DateAdjusters.EndOfMonth).Date) ); engine.SetValue( "startOfPreviousMonth", (Func) (instant => GetStartOfMonth(GetStartOfMonth(instant ?? clock.GetCurrentInstant()).Minus(Period.FromDays(14))) .Date) ); engine.SetValue( "plus", (Func) ((instant, duration) => instant.Plus(duration)) ); engine.SetValue( "minus", (Func) ((instant, duration) => instant.Minus(duration)) ); engine.SetValue( "durationFromSeconds", (Func) (Duration.FromSeconds) ); engine.SetValue( "durationFromMinutes", (Func) (Duration.FromMinutes) ); engine.SetValue( "durationFromHours", (Func) (Duration.FromHours) ); engine.SetValue( "durationFromDays", (Func) (Duration.FromDays) ); engine.SetValue( "formatInstant", (Func) ((instant, format, cultureInfo) => instant.ToString(format, cultureInfo ?? CultureInfo.InvariantCulture)) ); engine.SetValue( "localDateFromInstant", (Func) (instant => instant.InUtc().Date) ); engine.SetValue( "instantFromLocalDate", (Func) (value => value.AtStartOfDayInZone(DateTimeZone.Utc).ToInstant()) ); return Task.CompletedTask; } private LocalDateTime GetStartOfMonth(Instant instant) { return GetStartOfMonth(instant.InUtc().LocalDateTime); } private LocalDateTime GetStartOfMonth(LocalDateTime localDateTime) { return localDateTime.With(DateAdjusters.StartOfMonth); } } }