From 3a561570976e62b7c1d39fe6bb575d3939cb86ce Mon Sep 17 00:00:00 2001 From: Behzad Alizadeh Date: Tue, 5 May 2026 13:55:03 +0330 Subject: [PATCH] fix deadline activity with iran timezone --- .../Activities/Caspian/Deadline.cs | 57 +++++++++++++------ 1 file changed, 39 insertions(+), 18 deletions(-) diff --git a/src/modules/Elsa.Workflows.Core/Activities/Caspian/Deadline.cs b/src/modules/Elsa.Workflows.Core/Activities/Caspian/Deadline.cs index 8145f5a..2fa3e42 100644 --- a/src/modules/Elsa.Workflows.Core/Activities/Caspian/Deadline.cs +++ b/src/modules/Elsa.Workflows.Core/Activities/Caspian/Deadline.cs @@ -10,11 +10,13 @@ namespace Elsa.Workflows.Activities.Caspian; [Activity( Category = "Caspian", DisplayName = "Deadline", - Description = "Checks whether a configured deadline has expired." + Description = "Checks whether a configured deadline (UTC+03:30) has expired." )] [FlowNode("Valid", "Expired")] public class Deadline : Activity { + private static readonly TimeSpan IranOffset = TimeSpan.FromHours(3.5); + [Input( Description = "Variable name used to store the start time of the deadline.", DefaultValue = "DeadlineStartedAt" @@ -22,43 +24,62 @@ public class Deadline : Activity public Input VariableName { get; set; } = new("DeadlineStartedAt"); [Input( - Description = "The deadline duration (example: 48:00:00).", + Description = "Timeout duration in the format [d.]hh:mm:ss", DefaultValue = "48:00:00" )] public Input Timeout { get; set; } = new(TimeSpan.FromHours(48)); protected override async ValueTask ExecuteAsync(ActivityExecutionContext context) { - var variableName = context.Get(VariableName); + var variableName = context.Get(VariableName)!; var timeout = context.Get(Timeout); + var iranNow = DateTimeOffset.UtcNow.ToOffset(IranOffset); + // 1. مقدار رو می‌گیریم var startedAtObject = context.GetVariable(variableName); - if (startedAtObject == null) + // 2. با متد جدید پارس می‌کنیم که MinValue رو هم هندل می‌کنه + var startedTime = ParseDateTime(startedAtObject); + + // 3. اگر نال بود یا سال 0001، یعنی دفعه اوله و باید مقداردهی بشه + if (startedAtObject == null || startedTime == DateTimeOffset.MinValue) { - context.SetVariable(variableName, DateTimeOffset.UtcNow); - await context.ScheduleOutcomesAsync("Valid"); + context.SetVariable(variableName, iranNow); + await context.CompleteActivityWithOutcomesAsync("Valid"); return; } - var startedTime = ParseDateTime(startedAtObject); - var elapsed = DateTimeOffset.UtcNow - startedTime; + // 4. محاسبه زمان سپری شده + var elapsed = iranNow - startedTime; if (elapsed > timeout) - await context.ScheduleOutcomesAsync("Expired"); + await context.CompleteActivityWithOutcomesAsync("Expired"); else - await context.ScheduleOutcomesAsync("Valid"); + await context.CompleteActivityWithOutcomesAsync("Valid"); } - private DateTimeOffset ParseDateTime(object value) + private DateTimeOffset ParseDateTime(object? value) { - return value switch + if (value == null) return DateTimeOffset.MinValue; + + try { - DateTimeOffset dto => dto, - DateTime dt => new DateTimeOffset(dt), - JsonElement e when e.ValueKind == JsonValueKind.String => DateTimeOffset.Parse(e.GetString()!), - string s => DateTimeOffset.Parse(s), - _ => throw new InvalidCastException($"Cannot convert {value.GetType()} to DateTimeOffset") - }; + var dt = value switch + { + DateTimeOffset dto => dto, + DateTime dateTime => new DateTimeOffset(dateTime, IranOffset), + JsonElement e when e.ValueKind == JsonValueKind.String => + DateTimeOffset.TryParse(e.GetString(), out var res) ? res : DateTimeOffset.MinValue, + string s => DateTimeOffset.TryParse(s, out var res) ? res : DateTimeOffset.MinValue, + _ => DateTimeOffset.MinValue + }; + + // اگر مقدار معتبر بود، آفست ایران رو بهش اعمال کن + return dt == DateTimeOffset.MinValue ? dt : dt.ToOffset(IranOffset); + } + catch + { + return DateTimeOffset.MinValue; + } } }