mczachurski / wallpapper

:computer: Console application for creating dynamic wallpapers for macOS Mojave and newer

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Time-based HEIC not changing at the right times

ffxsam opened this issue · comments

This is my JSON:

[
  {
    "fileName": "Day.jpg",
    "isPrimary": true,
    "isForLight": true,
    "time": "2023-12-30T15:00:00Z"
  },
  {
    "fileName": "Evening.jpg",
    "isForDark": true,
    "time": "2023-12-31T01:00:00Z"
  },
  {
    "fileName": "Night.jpg",
    "time": "2023-12-31T07:00:00Z"
  },
  {
    "fileName": "Dawn.jpg",
    "time": "2023-12-31T11:00:00Z"
  },
  {
    "fileName": "Morning.jpg",
    "time": "2023-12-31T13:00:00Z"
  }
]

See the video below, and note the time I'm setting. That image that it changes to just past midnight is wrong (and I'm UTC-6, BTW). There's an image change at 7pm my time (01:00 UTC) and at 1am (07:00 UTC), nothing in between. Not sure why this is happening.

Broken.HEIC.mp4

I was just trying to sort this out today and it appears that you need to put your time zone offset in the timestamps. So if you are UTC-6, try replacing the "Z" at the end with "-06:00" (and of course pay attention to whether daylight savings time is in effect for the date that you specify and adjust your offset accordingly):

"time": "2023-12-30T15:00:00-06:00"

Things also seem to work better if your JSON entries match the order of the files in the file system. Pay attention to the order in which it reads in your images—surprisingly, it's not the order in which you have them in the JSON file.

The weird thing, if you deconstruct the official Apple ones, they're in UTC ISO format (ending in Z). Not sure why it doesn't work when I try this, though.

Thanks for the tip! I'll give it a shot if I decide to mess around with this again.

The actual plist in which the times are stored in the final HEIC doesn't have times at all. 8am for example is simply stored as the floating point value 0.33. Which makes sense, because the dynamic wallpapers always change at the same local time, no matter your time zone.

The value wallpapper will use is calculated here:

timeItem.time = (Double(hour) / 24.0) + (Double(min) / 60.0 / 24.0)

The code is intended to throw away everything except the hour and minute, then turn those two components into a Double representing the fraction of the day that has passed, but that is not what it does. Because the code uses an actual library to handle the dates, instead of just pulling the hour and minute values from the json, it undergoes several time zone conversions which are simply wrong. From my brief testing it seems that in aggregate, your local time zone is added twice, then the time zone in the time-stamp is subtracted from that (see example below).

For example if your local time is +01:00:

  • 08:00:00Z will become 0.41666666666666669 (10am)
  • 08:00:00+01:00 will become 0.375 (9am)
  • 08:00:00+02:00 will become 0.33333333333333331 (actually 8am)

This explains why your image changes at 7pm and 1am (your timezone being -06:00 causes it to be wrong by 6 hours, since it subtracts 12 hours from your UTC timestamps). That one of the changes ends up being around midnight might be caused by it actually ending up with a negative value somewhere along the line, which then becomes zero (plus rounding errors), not sure though.

Either way, you should get the correct times, if you specify -12:00 as the time zone offset (no, really) and then just give the local times you want the images to change at. If the problem remains, you could have a look at the actual plist that gets generated.

In order to get the plist in a human-readable form:

wallpapper -e output.heic -o output.plist
plistutil -i output.list -f json -o output.json

The json file will contain an object ap which gives the (zero-based) indices of the isForLight and isForDark images, as well as an array ti, which maps times (given as fractions) to indices of images to show.

If your output were working correctly, you'd expect it to look roughly like this:

{
    "ti": [
        {
            "t": 0.375,
            "i": 0
        },
        {
            "t": 0.79166667,
            "i": 1
        },
        {
            "t": 0.04166667,
            "i": 2
        },
        {
            "t": 0.20833333,
            "i": 3
        },
        {
            "t": 0.29166667,
            "i": 4
        }
    ],
    "ap": {
        "d": 1,
        "l": 0
    }
}