Description
Describe the feature
Logging this here as it's .NET-specific, so if not implemented for provided.al2023
, it might be something desired for any forthcoming .NET 8 managed runtime.
I migrated a .NET 8 application using the provided.al2
runtime which uses the TimeZoneInfo.FindSystemTimeZoneById()
method to convert UTC times to a specific time zone to provided.al2023
earlier this week, and have discovered that compared to the previous version of the provided runtime, tzdb is not installed. Calling the TimeZoneInfo.GetSystemTimeZones()
method returns 0 items as well.
This causes code paths using built-in .NET time zone handling APIs that typically work outside of the Lambda runtime environment (e.g. Linux build agents, developers' Windows machines) to fail when deployed to AWS Lambda.
To fix the functionality in the application, I've had to re-introduce a dependency on NodaTime (we used to use this, but removed it in favour of the new TimeProvider
API).
+ using NodaTime;
var utcNow = TimeProvider.System.GetUtcNow();
- var timeZone = TimeZoneInfo.FindSystemTimeZoneById("Europe/London");
- var localNow = TimeZoneInfo.ConvertTimeFromUtc(utcNow, timeZone);
+ var timeZone = DateTimeZoneProviders.Tzdb["Europe/London"];
+ var localNow = Instant.FromDateTimeUtc(utcNow).InZone(timeZone).ToDateTimeUnspecified();
Use Case
The application converts times in UTC to a specific time zone. For example:
var utcNow = TimeProvider.System.GetUtcNow();
var timeZone = TimeZoneInfo.FindSystemTimeZoneById("Europe/London");
var nowLocal = TimeZoneInfo.ConvertTimeFromUtc(utcNow, timeZone);
With tzdb installed, this code will work correctly.
Without it, an exception is thrown at runtime:
System.TimeZoneNotFoundException: The time zone ID 'Europe/London' was not found on the local computer.
---> System.IO.DirectoryNotFoundException: Could not find a part of the path '/usr/share/zoneinfo/Europe/London'.
at Interop.ThrowExceptionForIoErrno(ErrorInfo errorInfo, String path, Boolean isDirError)
at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String path, OpenFlags flags, Int32 mode, Boolean failForSymlink, Boolean& wasSymlink, Func`4 createOpenException)
at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, UnixFileMode openPermissions, Int64& fileLength, UnixFileMode& filePermissions, Boolean failForSymlink, Boolean& wasSymlink, Func`4 createOpenException)
at System.IO.Strategies.OSFileStreamStrategy..ctor(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Nullable`1 unixCreateMode)
at System.TimeZoneInfo.ReadAllBytesFromSeekableNonZeroSizeFile(String path, Int32 maxFileSize)
at System.TimeZoneInfo.TryGetTimeZoneFromLocalMachineCore(String id, TimeZoneInfo& value, Exception& e)
--- End of inner exception stack trace ---
at System.TimeZoneInfo.FindSystemTimeZoneById(String id)
Proposed Solution
Install tzdb
on the provided.al2023
runtime (or the managed .NET 8 runtime if/when it becomes available).
As well as making the code functional as with provided.al2
, it removes the need to include NodaTime in the function's deployment package.
Other Information
No response
Acknowledgements
- I may be able to implement this feature request
- This feature might incur a breaking change
AWS .NET SDK and/or Package version used
The provided.al2023
runtime.
Targeted .NET Platform
.NET 8
Operating System and version
Amazon Linux 2023