All Downloads are FREE. Search and download functionalities are using the official Maven repository.

laika.config.PlatformDateTimeImpl.scala Maven / Gradle / Ivy

/*
 * Copyright 2012-2020 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package laika.config

import cats.syntax.all.*

import scala.scalajs.js
import scala.util.Try

/** @author Jens Halm
  */
private[laika] object PlatformDateTimeImpl extends PlatformDateTime {

  type Type = js.Date

  private[laika] def now: Type = new js.Date()

  def parse(dateString: String): Either[String, Type] = {
    val result = new js.Date(dateString)
    if (result.getTime().isNaN) Left(s"Invalid date format: $dateString")
    else Right(result)
  }

  private def jsLocaleParam(locale: Option[String]): js.Any =
    locale.map(js.Any.fromString).getOrElse(new js.Array())

  private[laika] def format(
      date: Type,
      pattern: String,
      locale: Option[String] = None
  ): Either[String, String] = {
    /*
    Formatting based on an explicit pattern is not supported for JavaScript Dates.
    The specified pattern is therefore mostly ignored, apart from looking for a colon as a hint whether
    a time component should be included.

    A proper way to handle this would be to parse the pattern and translate it to a JavaScript options object,
    but this is currently considered beyond the scope of Laika.
    For this reason this is currently not public API.
     */
    val attempt = {
      if (pattern.contains(":"))
        Try(
          date
            .asInstanceOf[js.Dynamic]
            .toLocaleString(
              jsLocaleParam(locale)
            ) // arguments not supported by core Scala.js, hence the dynamic approach
            .asInstanceOf[String]
        )
      else
        Try(
          date
            .asInstanceOf[js.Dynamic]
            .toLocaleDateString(jsLocaleParam(locale))
            .asInstanceOf[String]
        )
    }
    attempt.toEither.left.map(_.getMessage)
  }

  private lazy val formatterConstants = Set("full", "long", "medium", "short")

  private[laika] def formatConstant(
      date: Type,
      constant: String,
      locale: Option[String] = None
  ): Option[Either[String, String]] =
    if (formatterConstants.contains(constant.toLowerCase)) {
      val opts = js.Dynamic.literal(
        "dateStyle" -> constant.toLowerCase,
        "timeStyle" -> constant.toLowerCase
      )
      Try(
        date
          .asInstanceOf[js.Dynamic]
          .toLocaleString(
            jsLocaleParam(locale),
            opts
          ) // arguments not supported by core Scala.js, hence the dynamic approach
          .asInstanceOf[String]
      )
        .toEither
        .leftMap(_.getMessage)
        .some
    }
    else None

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy