Skip to content

Install tzdb on provided.al2023 runtime so that TimeZoneInfo.FindSystemTimeZoneById() works #1620

Closed
@martincostello

Description

@martincostello

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

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions