fix deadline activity with iran timezone

This commit is contained in:
Behzad Alizadeh
2026-05-05 13:55:03 +03:30
parent b859e20a01
commit 3a56157097
@@ -10,11 +10,13 @@ namespace Elsa.Workflows.Activities.Caspian;
[Activity( [Activity(
Category = "Caspian", Category = "Caspian",
DisplayName = "Deadline", DisplayName = "Deadline",
Description = "Checks whether a configured deadline has expired." Description = "Checks whether a configured deadline (UTC+03:30) has expired."
)] )]
[FlowNode("Valid", "Expired")] [FlowNode("Valid", "Expired")]
public class Deadline : Activity public class Deadline : Activity
{ {
private static readonly TimeSpan IranOffset = TimeSpan.FromHours(3.5);
[Input( [Input(
Description = "Variable name used to store the start time of the deadline.", Description = "Variable name used to store the start time of the deadline.",
DefaultValue = "DeadlineStartedAt" DefaultValue = "DeadlineStartedAt"
@@ -22,43 +24,62 @@ public class Deadline : Activity
public Input<string> VariableName { get; set; } = new("DeadlineStartedAt"); public Input<string> VariableName { get; set; } = new("DeadlineStartedAt");
[Input( [Input(
Description = "The deadline duration (example: 48:00:00).", Description = "Timeout duration in the format [d.]hh:mm:ss",
DefaultValue = "48:00:00" DefaultValue = "48:00:00"
)] )]
public Input<TimeSpan> Timeout { get; set; } = new(TimeSpan.FromHours(48)); public Input<TimeSpan> Timeout { get; set; } = new(TimeSpan.FromHours(48));
protected override async ValueTask ExecuteAsync(ActivityExecutionContext context) protected override async ValueTask ExecuteAsync(ActivityExecutionContext context)
{ {
var variableName = context.Get(VariableName); var variableName = context.Get(VariableName)!;
var timeout = context.Get(Timeout); var timeout = context.Get(Timeout);
var iranNow = DateTimeOffset.UtcNow.ToOffset(IranOffset);
// 1. مقدار رو می‌گیریم
var startedAtObject = context.GetVariable<object>(variableName); var startedAtObject = context.GetVariable<object>(variableName);
if (startedAtObject == null) // 2. با متد جدید پارس می‌کنیم که MinValue رو هم هندل می‌کنه
var startedTime = ParseDateTime(startedAtObject);
// 3. اگر نال بود یا سال 0001، یعنی دفعه اوله و باید مقداردهی بشه
if (startedAtObject == null || startedTime == DateTimeOffset.MinValue)
{ {
context.SetVariable(variableName, DateTimeOffset.UtcNow); context.SetVariable(variableName, iranNow);
await context.ScheduleOutcomesAsync("Valid"); await context.CompleteActivityWithOutcomesAsync("Valid");
return; return;
} }
var startedTime = ParseDateTime(startedAtObject); // 4. محاسبه زمان سپری شده
var elapsed = DateTimeOffset.UtcNow - startedTime; var elapsed = iranNow - startedTime;
if (elapsed > timeout) if (elapsed > timeout)
await context.ScheduleOutcomesAsync("Expired"); await context.CompleteActivityWithOutcomesAsync("Expired");
else 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
{
var dt = value switch
{ {
DateTimeOffset dto => dto, DateTimeOffset dto => dto,
DateTime dt => new DateTimeOffset(dt), DateTime dateTime => new DateTimeOffset(dateTime, IranOffset),
JsonElement e when e.ValueKind == JsonValueKind.String => DateTimeOffset.Parse(e.GetString()!), JsonElement e when e.ValueKind == JsonValueKind.String =>
string s => DateTimeOffset.Parse(s), DateTimeOffset.TryParse(e.GetString(), out var res) ? res : DateTimeOffset.MinValue,
_ => throw new InvalidCastException($"Cannot convert {value.GetType()} to DateTimeOffset") 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;
}
} }
} }