ddev / ddev

Docker-based local PHP+Node.js web development environments
https://ddev.com
Apache License 2.0
2.66k stars 592 forks source link

DDEV could default timezone to the user's timezone #6458

Closed rfay closed 3 weeks ago

rfay commented 1 month ago

Is there an existing issue for this?

Is your feature request related to a problem?

It would be reasonable for a project timezone to default to the user's timezone if not otherwise set.

Slack conversation with @mandclu: https://drupal.slack.com/archives/C5TQRQZRR/p1722436802700439

I think this would also mostly solve the request in

Describe your solution

The host-side timezone is available in date +%Z

I think it might work just fine to use that output as the project's default timezone

Describe alternatives

Do the requested global config timezone:

Additional context

Interested in your reaction @tyler36

tyler36 commented 1 month ago

Was thinking about this over the weekend after following @mandclu thread on slack.

I think having a global setting is great for config parity with project config and beginner developers. Developing with containers can be a tricky concept and this would make it easier and be a reasonable assumption.

However, now I'm leaning if it's important enough to your project, it should be in the repo; DDEV project config, or framework config, Eg. Drush config export, Laravel's config/app.php.

rfay commented 1 month ago

We could do both, of course. It could be a global setting, a project setting, and take the default from the host.

tyler36 commented 1 month ago

We could do both, of course. It could be a global setting, a project setting, and take the default from the host.

Seems reasonable to me.

stasadev commented 1 month ago

I tried

$ date +%Z
EEST

And TZ=EEST was added inside the container, but it is not recognized as a real timezone, because we need to have something like TZ=Europe/Kyiv to make it work.

We can try this (or find another command):

$ timedatectl | grep -i "Time zone" | awk '{print $3}'
Europe/Kyiv
rfay commented 1 month ago

Looking at Go's LoadLocation I was excited to see Local but it doesn't help.

// If the name is "" or "UTC", LoadLocation returns UTC.
// If the name is "Local", LoadLocation returns Local.
//
// Otherwise, the name is taken to be a location name corresponding to a file
// in the IANA Time Zone database, such as "America/New_York".
//
// LoadLocation looks for the IANA Time Zone database in the following
// locations in order:
//
//   - the directory or uncompressed zip file named by the ZONEINFO environment variable
//   - on a Unix system, the system standard installation location
//   - $GOROOT/lib/time/zoneinfo.zip
//   - the time/tzdata package, if it was imported

Unfortunately, if we don't have a reliable cross-platform way to get a usable timezone, this idea won't work I don't think.

mbomb007 commented 1 month ago

You'd probably have to maintain a manual mapping of short timezone to the IANA identifier. Created with the help of AI:

package main

import (
    "fmt"
    "time"
)

// timezoneMap maps short timezone abbreviations to their IANA equivalents.
var timezoneMap = map[string]string{
    "UTC": "UTC",
    "CDT": "America/Chicago",
    "CST": "America/Chicago",
    "MDT": "America/Denver",
    "MST": "America/Denver",
    "PDT": "America/Los_Angeles",
    "PST": "America/Los_Angeles",
    "EDT": "America/New_York",
    "EST": "America/New_York",
    "AEDT": "Australia/Sydney",
    "AEST": "Australia/Sydney",
    // Add more mappings as needed
}

// ShortToIANA converts a short timezone abbreviation to its IANA equivalent.
func ShortToIANA(shortTZ string) (string) {
    iANA, ok := timezoneMap[shortTZ]
    if !ok {
        return ""
    }
    return iANA
}

func main() {
    location, err := time.LoadLocation("Local")
    if err != nil {
        fmt.Println("Error loading location:", err)
        return
    }

    localTime := time.Now().In(location)
    zone, _ := localTime.Zone()
    iANA := ShortToIANA(zone)
    if iANA != "" {
        fmt.Printf("Timezone: %s\n", iANA)
    } else {
        fmt.Printf("Unknown short timezone abbreviation: %s\n", zone)
    }
}
rfay commented 1 month ago

Thanks to you and AI :)

You'd have to cover a lot more than that to be predictable and comprehensive :)

mbomb007 commented 1 month ago

Yeah. Unfortunately, Golang doesn't seem to have a nice library for that.

stasadev commented 1 month ago

maintain a manual mapping of short timezone to the IANA identifier

Unfortunately, this is impossible to do because some abbreviations may overlap.

For example, CST may be one of:

I found a general solution (which works almost everywhere):