Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Date plugin: Format the date from frontmatter exactly as I specified it #555

Open
brookback opened this issue Jan 19, 2024 · 7 comments
Open
Labels
enhancement New feature or request

Comments

@brookback
Copy link

brookback commented Jan 19, 2024

Enter your suggestions in details:

Hi! Not sure I'm holding this wrong, but I've got a (deceivingly simple) date problem.

Request

I want the specified date and time from my Markdown frontmatter to show in the built site. Currently, all dates and times are formatted in UTC (or whatever TZ is on the machine building the site).

Use case

For the date field in my posts' frontmatter, I use my current local time with time zone offset. Like this:

---
date: 2024-01-18 20:44:58 +7
location: Koh Lanta, Thailand
---

Note the included timezone offset.

When formatting that in the templates, I want that date and time to show. It works on my machine (classic!), but when building on CI for deploying, dates are showing in UTC.

Using the format string PPP — HH:mm:

January 18th, 2024 — 13:44

when I want:

January 18th, 2024 — 20:44

I just want whatever I input as the formatted output 😄

I've read about setting the TZ var when building with lume, but I can't do that, since the local time for each post might vary (I might post across timezones).

Also, I can't do my own hacky date parsing and formatting, since I don't have access to the raw frontmatter record on the Page data: I only have the already parsed date: Date.

Maybe this is out of scope for Lume, but I thought I'd ask. Thanks for a never ending great job ❤️


Info

  • Lume version: v1.13.1
  • OS: macOS 14.2.1

Related:

@brookback brookback added the enhancement New feature or request label Jan 19, 2024
@oscarotero
Copy link
Member

As an idea, you can preprocess the pages to change the Date. Let's say you create a new variable with the time zone:

date: 2024-01-18 20:44:58
timezone: Asia/Bangkok

And then process the pages assigning the correct timezone.

Lume 2 uses Temporal polyfill (in /deps/temporal.ts) which has functions to work with timezones (see docs here).

Let me know if you can solve it with this. If it works fine, maybe this could be a Lume plugin (Some people ask me about using different timezones in multilanguage sites).

@brookback
Copy link
Author

@oscarotero Thanks for replying.

Yes, that'd work too, with the added benefit of documentation in the frontmatter.

But if not, would it be improper to suggest that Lume provides the frontmatter as a part of the Page interface somewhere? As I touched upon in:

Also, I can't do my own hacky date parsing and formatting, since I don't have access to the raw frontmatter record on the Page data: I only have the already parsed date: Date.

As "raw" as possible, meaning, no string → Date parsing whatsoever. Just raw strings (and maybe number | boolean :)).

Or do you consider it leaky?

@oscarotero
Copy link
Member

That's no easy. The date parsing is not performed by Lume, but by yaml parsed https://deno.land/[email protected]/front_matter/mod.ts

@kollhof
Copy link

kollhof commented Aug 16, 2024

I have only just started using Lume an ran into the same challenge that original timezone offsets do not make it into the page's date object, which is to be expected with JavaScript Date objects. I would have hoped the raw string would still be there somewhere, but I could not find it.

I believe it happens in:

return new Date(getZonedDateTime(date).epochMilliseconds);

front_matter appears to just return the raw string, from what I can tell:

> extractYaml(`---
date: '2016-01-01T15:42:00.001+11:00'
---
`)
{
  frontMatter: "date: '2016-01-01T15:42:00.001+11:00'",
  body: "",
  attrs: { date: "2016-01-01T15:42:00.001+11:00" }
}

Lume is using Temporal internally to parse the string, but is converting it to a Date object, rather than returning e.g. a ZonedDateTime, which would preserve all info.

Temporal.ZonedDateTime.from("2016-01-01T15:42:00+11:00[Australia/Sydney]")

A date with offset "2016-01-01T15:42:00+11:00 but without timezone info (e.g. [Australia/Sydney]) would not work, if I read the docs correctly, though.
So, all your date strings would need to include the timezone. Otherwise Lume would need to use Temporal.Instant which would also loose the parsed offset information.

It would be great if Lume either preserved the original unparsed date (or whole plain front_matter object) in the page data or provide a hook for parsing it. Asite.prepprocess hook already is already too late, as the date has already been parsed.

@brookback
Copy link
Author

@kollhof Nice find, I didn't know Lume was using Temporal internally.

Out of curiosity, how do you plan on formatting the timezone-aware dates in your markup?

I'd love for this end-to-end flow to work:

  1. Have an ISO date with timezone date: "2016-01-01T15:42:00+11:00[Australia/Sydney]" in the frontmatter.
  2. Lume keeps this exact ISO string somewhere on the page's data object for me to do things with, if needed. Also parse it to a Temporal.ZonedDateTime and keep on the page data.
  3. When formatting — maybe with the date filter — the timezone is carried through and taken into consideration when formatting according to some string or with the Intl API.

@oscarotero
Copy link
Member

Lume uses Temporal internally to parse the date if it wasn't already parsed by the yaml parser. If the date is unquoted, the YAML package (from std) parse it automatically (here's the code):

date: 2016-01-01T15:42:00.001+11:00   # parsed by @std/yaml
date: '2016-01-01T15:42:00.001+11:00' # parsed by lume

What Lume does is to normalize the Date parsing to match yaml behavior in those cases in which the date is not parsed by yaml: i.e. if it's exported as a quoted date, if has a special value like Git Created or if it's included in the filename (2016-01-01-example.md).

As an idea, you can use a different named variable to store the date as you want. For example, tz_date to store the time zoned date (must be quoted, to prevent being parsed by YAML parser):

tz_date: '2016-01-01T15:42:00.001+11:00'

Then, you can create a preprocessor to parse the date as you want and even modify the date variable if you need to.

@kollhof
Copy link

kollhof commented Aug 16, 2024

Interesting, I was not aware of the yaml parser doing that, thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants