sebastienros/fluid

TimeZone from TemplateContext is not working

Opened this issue · 5 comments

Fluid.Core Version: 2.4.0
.NET Version: .NET 7
OS: mac os 13.2.1 (22D68)

I ran into an issue that dates are not getting converted into TimeZone specified in TimeZone property of TemplateContext, please find below simple repro code

csproj

<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>net7.0</TargetFramework>
        <ImplicitUsings>enable</ImplicitUsings>
        <Nullable>enable</Nullable>
    </PropertyGroup>

    <ItemGroup>
        <PackageReference Include="Fluid.Core" Version="2.4.0" />
    </ItemGroup>

</Project>

Program.cs

using Fluid;

const string text = "My name is {{ Name }} age is {{ Age }} years old birth date {{ BirthDate }}";

var date = new DateTime(2022, 2, 2, 12, 0, 0, DateTimeKind.Utc);
var timezone = TimeZoneInfo.FindSystemTimeZoneById("Europe/Uzhgorod");

var data = new TestClass
{
    Age = 22,
    Name = "Bill",
    BirthDate = date
};

var parser = new FluidParser();

var template = parser.Parse(text);

var context = new TemplateContext(data, new TemplateOptions
{
    TimeZone = timezone
});

var result = template.Render(context);

Console.WriteLine("Result:");
Console.WriteLine(result);

Console.WriteLine();
Console.WriteLine($"Date in UTC TZ           : {data.BirthDate:u}");
Console.WriteLine($"Expected Date in Local TZ: {TimeZoneInfo.ConvertTime(data.BirthDate, timezone):u}");

public class TestClass
{
    public string Name { get; set; }

    public int Age { get; set; }

    public DateTime BirthDate { get; set; }
}

Program output

Result:
My name is Bill age is 22 years old birth date 2022-02-02 12:00:00Z

Date in UTC TZ           : 2022-02-02 12:00:00Z
Expected Date in Local TZ: 2022-02-02 14:00:00Z

I thought that Fluid should convert UTC date into a timezone specified in TemplateContext.TimeZone property, or am i missing something?

Thanks for any help in advance!

odesyatnyk, did you have a workaround solution for it? I got the same issue as you.

These are only used for parsing date/times. When rendering it's using the one that is set to the date value: https://github.com/sebastienros/fluid#time-zones

You can use the one in options by doing {{ BirthDate | time_zone: 'local' }}

If you want to convert all date/times to a specific timezone before they are rendered so you don't have to set a time zone, you can configure a value converter: https://github.com/sebastienros/fluid#adding-a-value-converter

Reopening the issue since this should be added to the documentation.

@dangduyquang yes, i figured it out, the way exactly as @sebastienros described it
sorry that i forgot to share it here, if you need here is the final working sample

using Fluid;

const string text = "My name is {{ Name }} age is {{ Age }} years old birth date {{ BirthDate | time_zone: 'local' | format_date: 'MM/dd/yyyy hh:mm tt' }}";

var date = new DateTime(2022, 2, 2, 12, 0, 0, DateTimeKind.Utc);
var timezone = TimeZoneInfo.FindSystemTimeZoneById("Europe/Uzhgorod");

var data = new TestClass
{
    Age = 22,
    Name = "Bill",
    BirthDate = date
};

var parser = new FluidParser();

var template = parser.Parse(text);

var context = new TemplateContext(data, new TemplateOptions
{
    TimeZone = timezone
});

var result = template.Render(context);

Console.WriteLine("Result:");
Console.WriteLine(result);

Console.WriteLine();
Console.WriteLine($"Date in UTC TZ           : {data.BirthDate:u}");
Console.WriteLine($"Expected Date in Local TZ: {TimeZoneInfo.ConvertTime(data.BirthDate, timezone):u}");

public class TestClass
{
    public string Name { get; set; }

    public int Age { get; set; }

    public DateTime BirthDate { get; set; }
}

@odesyatnyk, thank you for your information. The solution is working for me now.