# kate: default-dictionary en_US

## This file is part of the 'stringi' package for R.
## Copyright (c) 2013-2024, Marek Gagolewski <https://www.gagolewski.com/>
## All rights reserved.
##
## Redistribution and use in source and binary forms, with or without
## modification, are permitted provided that the following conditions are met:
##
## 1. Redistributions of source code must retain the above copyright notice,
## this list of conditions and the following disclaimer.
##
## 2. Redistributions in binary form must reproduce the above copyright notice,
## this list of conditions and the following disclaimer in the documentation
## and/or other materials provided with the distribution.
##
## 3. Neither the name of the copyright holder nor the names of its
## contributors may be used to endorse or promote products derived from
## this software without specific prior written permission.
##
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
## 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
## BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
## FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
## HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
## OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
## OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
## EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


#' @title
#' List Available Time Zone Identifiers
#'
#' @description
#' Returns a list of available time zone identifiers.
#'
#' @details
#' If \code{offset} and \code{region} are \code{NA} (the default), then
#' all time zones are returned. Otherwise,
#' only time zone identifiers with a given raw offset from GMT
#' and/or time zones corresponding to a given region are provided.
#' Note that the effect of daylight savings time is ignored.
#'
#' A time zone represents an offset applied to the Greenwich Mean Time (GMT)
#' to obtain local time (Universal Coordinated Time, or UTC, is similar,
#' but not precisely identical, to GMT; in \pkg{ICU} the two terms
#' are used interchangeably since \pkg{ICU} does not concern itself with
#' either leap seconds or historical behavior).
#' The offset might vary throughout the year, if daylight savings time (DST)
#' is used, or might be the same all year long.
#' Typically, regions closer to the equator do not use DST.
#' If DST is in use, then specific rules define the point where
#' the offset changes and the amount by which it changes.
#'
#' If DST is observed, then three additional bits of information are needed:
#' \enumerate{
#' \item The precise date and time during the year when DST begins.
#' In the first half of the year it is in the northern hemisphere,
#' and in the second half of the year it is in the southern hemisphere.
#' \item The precise date and time during the year when DST ends.
#' In the first half of the year it is in the southern hemisphere,
#' and in the second half of the year it is in the northern hemisphere.
#' \item The amount by which the GMT offset changes when DST is in effect.
#' This is almost always one hour.
#' }
#'
#'
#' @param offset single numeric value;
#' a given raw offset from GMT, in hours;
#' \code{NA} for all offsets
#' @param region single string;
#' a ISO 3166 two-letter country code or UN M.49 three-digit area code;
#' \code{NA} for all regions
#'
#' @return Returns a character vector.
#'
#' @references
#' \emph{TimeZone} class -- ICU API Documentation,
#' \url{https://unicode-org.github.io/icu-docs/apidoc/dev/icu4c/classicu_1_1TimeZone.html}
#'
#' \emph{ICU TimeZone classes} -- ICU User Guide,
#' \url{https://unicode-org.github.io/icu/userguide/datetime/timezone/}
#'
#' \emph{Date/Time Services} -- ICU User Guide,
#' \url{https://unicode-org.github.io/icu/userguide/datetime/}
#'
#' @examples
#' stri_timezone_list()
#' stri_timezone_list(offset=1)
#' stri_timezone_list(offset=5.5)
#' stri_timezone_list(offset=5.75)
#' stri_timezone_list(region='PL')
#' stri_timezone_list(region='US', offset=-10)
#'
#' # Fetch information on all time zones
#' do.call(rbind.data.frame,
#'    lapply(stri_timezone_list(), function(tz) stri_timezone_info(tz)))
#'
#' @family datetime
#' @family timezone
#' @export
stri_timezone_list <- function(region=NA_character_, offset=NA_integer_)
{
    stri_sort(
        .Call(C_stri_timezone_list, region, offset),
        locale="en_US", numeric=TRUE, strength=1
    )
}


#' @title
#' Set or Get Default Time Zone in \pkg{stringi}
#'
#' @description
#' \code{stri_timezone_set} changes the current default time zone for all functions
#' in the \pkg{stringi} package, i.e., establishes the meaning of the
#' ``\code{NULL} time zone'' argument to date/time processing functions.
#'
#' \code{stri_timezone_get} gets the current default time zone.
#'
#' For more information on time zone representation in \pkg{ICU}
#' and \pkg{stringi}, refer to \code{\link{stri_timezone_list}}.
#'
#' @details
#' Unless the default time zone has already been set using
#' \code{stri_timezone_set}, the default time zone is determined
#' by querying the OS with methods in \pkg{ICU}'s internal platform utilities.
#'
#' @param tz single string; time zone identifier
#'
#' @return
#' \code{stri_timezone_set} returns a string with
#' previously used timezone, invisibly.
#'
#' \code{stri_timezone_get} returns a single string
#' with the current default time zone.
#'
#' @references
#' \emph{TimeZone} class -- ICU API Documentation,
#' \url{https://unicode-org.github.io/icu-docs/apidoc/dev/icu4c/classicu_1_1TimeZone.html}
#'
#' @examples
#' \dontrun{
#' oldtz <- stri_timezone_set('Europe/Warsaw')
#' # ... many time zone-dependent operations
#' stri_timezone_set(oldtz) # restore previous default time zone
#' }
#'
#' @export
#' @family datetime
#' @family timezone
#' @rdname stri_timezone_set
#' @export
stri_timezone_get <- function()
{
    stri_timezone_info()$ID
}


#' @rdname stri_timezone_set
#' @export
stri_timezone_set <- function(tz)
{
    previous <- stri_timezone_get()
    .Call(C_stri_timezone_set, tz)
    invisible(previous)
}


#' @title
#' Query a Given Time Zone
#'
#' @description
#' Provides some basic information on a given time zone identifier.
#'
#' @details
#' Used to fetch basic information
#' on any supported time zone.
#'
#' For more information on time zone representation in \pkg{ICU},
#' see \code{\link{stri_timezone_list}}.
#'
#' @param tz \code{NULL} or \code{''} for default time zone,
#' or a single string with time zone ID otherwise
#' @param display_type single string;
#' one of \code{'short'}, \code{'long'}, \code{'generic_short'},
#' \code{'generic_long'}, \code{'gmt_short'}, \code{'gmt_long'},
#' \code{'common'}, \code{'generic_location'}
#' @param locale \code{NULL} or \code{''} for default locale,
#' or a single string with locale identifier
#'
#' @return
#' Returns a list with the following named components:
#' \enumerate{
#' \item \code{ID} (time zone identifier),
#' \item \code{Name} (localized human-readable time zone name),
#' \item \code{Name.Daylight} (localized human-readable time zone
#' name when DST is used, if available),
#' \item \code{Name.Windows} (Windows time zone ID, if available),
#' \item \code{RawOffset} (raw GMT offset, in hours, before taking
#' daylight savings into account), and
#' \item \code{UsesDaylightTime} (states whether a time zone uses
#' daylight savings time in the current Gregorian calendar year).
#' }
#'
#' @examples
#' stri_timezone_info()
#' stri_timezone_info(locale='sk_SK')
#' sapply(c('short', 'long', 'generic_short', 'generic_long',
#'          'gmt_short', 'gmt_long', 'common', 'generic_location'),
#'   function(e) stri_timezone_info('Europe/London', display_type=e))
#'
#' @family datetime
#' @family timezone
#' @export
stri_timezone_info <- function(tz=NULL, locale=NULL, display_type="long")
{
    # TODO: when does DST start???
    .Call(C_stri_timezone_info, tz, locale, display_type)
}
