Commit iniziale

This commit is contained in:
Paolo A
2025-02-18 22:59:07 +00:00
commit 4bbf35cefb
6879 changed files with 623784 additions and 0 deletions

410
node_modules/@js-joda/core/CHANGELOG.md generated vendored Normal file
View File

@@ -0,0 +1,410 @@
Changelog
=========
### Later version
For later versions check the global [`CHANGELOG.md`](../../CHANGELOG.md) file in the root folder.
### 5.1.0
* [#578](https://github.com/js-joda/js-joda/pull/578) Cleanup typings ([@StrayAlien](https://github.com/StrayAlien))
### 5.0.0
* [#574](https://github.com/js-joda/js-joda/pull/574) Reverting babel targets for UMD ([@pithu](https://github.com/pithu))
* [#548](https://github.com/js-joda/js-joda/pull/548) Disallowing implicit conversion of Temporal/TemporalAmount to numeric values ([@InExtremaRes](https://github.com/InExtremaRes))
### 4.3.0
* [#567](https://github.com/js-joda/js-joda/pull/567) Remove generated distributions files from git ([@pithu](https://github.com/pithu))
* [#564](https://github.com/js-joda/js-joda/pull/564) Fix travis for PR's from forks ([@pithu](https://github.com/pithu))
### 4.2.1
* [#559](https://github.com/js-joda/js-joda/pull/559) Fix references to deprecated single repos ([@pithu](https://github.com/pithu))
### 4.2.0
* Upgrade dependencies #555 by @pithu
* Change @babel/preset-env targets, fix IE11 issues #555 by @pithu
* Improve documentation #556 by @pithu
### 4.1.0
* Remove edge case handling for Temporal.minus #542 by @pithu
* Improve docu #550 by @pithu
### 4.0.0
Even this is a major release, there are no real breaking changes.
The release contains typescript definition cleanup and some
"private" methods have been prefixed with "_". These methods are intended for internal use only.
If you used the threeten API in the intended way, there shouldn't be any breaking changes.
If you used internal methods before, there is an replacement eg instead of `minusAmountUnit` use `minus`.
* cleanup TS Typings in #456 by @InExtremaRes
* cleanup private methods and Temporal class in #460 by @InExtremaRes
* remove TS definitions from core, moved to locale TS definitions in #389 by @InExtremaRes
* make .equals a type predicate in the TS typings in #457 by @InExtremaRes
* add some ISO formatters in #455 by @akonior
* several dependabot updates
### 3.2.0
* add typescript definitions for OffsetDateTime and OffsetTime #448 by jonfreedman
### 3.1.0
* Fix bitwise or #439 by @pithu
* Tests for TS declaration run with ts-node #423 by InExtremaRes
* dependabot Bump elliptic from 6.5.2 to 6.5.3
* dependabot Bump lodash from 4.17.15 to 4.17.19
* dependabot Bump npm-registry-fetch from 4.0.2 to 4.0.5
### 3.0.0
This is a major release because of these following minor/ breaking cleanups:
* Renamed method getDisplayName to displayName for
* WeekFields
* DayOfWeek
* Month
* IsoFields
* Removed duplicate function YearMonth.with(number, number)
* YearMonth.with(year, month), use YearMonth.of() instead
* YearMonth.withYearMonth(year, month), use YearMonth.of() instead
All updates:
* Implement OffsetTime and OffsetDateTim #416 by exoego
* TS types reorganized and documentation added #418 by InExtremaRes
* Fix isBrowserTest check #419 by pithu
* Duration#(minus|plus) should accept TemporalUnit, not just ChronoUnit #417 by exoego
* TS types refactor part 1 #415 by InExtremaRes
* Remove YearMonth#with that takes (number, number) #412 by InExtremaRes
* Fixes and cleanups to TemporalFields and TemporalUnits #408 by InExtremaRes
* Switch to travis-ci.com #409 by pithu
* Error base name changed to "JsJodaException" and exceptions exposed in TS #407 by InExtremaRes
* Some fixes to TS declarations #404 by InExtremaRes
* remove android saucelabs test setup #403 by pithu
* Fix TS declarations of some TemporalAdjuster implementations (like DayOfWeak) #402 by InExtremaRes
* Fixed types of DateTimeFormatterBuilder.prototype.toFormatter to allow zero arguments #388 by InExtremaRes
* Add missing types for Clock.offset() #387 by InExtremaRes
* Added missing nanoAdjustment to Duration.ofSeconds static method #383 by jseter
* changed bitwise or to logical or #379 by bowersj
* Add Typescript for IsoChronology.INSTANCE #373 by cranberyxl
* Remove `withTemporalAdjuster` and others non-public methods from TS declaration #363 by InExtremaRes
### 2.0.0
This is a major release because some 'internal' methods were hidden from the typescript definitions
and were renamed in the javascript code.
Resolve those conflicts by using the 'public shorthand' methods, like instead of using `with*()` use `with(...)`.
* Improve of the TS declarations #353 from InExtremaRes
* Add missing methods to `Temporal` interface #361 from thrucker
* LocalDateTime.of requires at least 3 arguments #356
### 1.12.0
* Cleanup documentation and configuration
* Upgrade dependencies
* Add ISO formatters definitions #358 akonior/iso-formetters
* Improve TS declarations with no breaking change #357 InExtremaRes/ts-declarations
* Fixes to docu and LocalDateTime.of() according to the typescript changes #359
### 1.11.0
* Added ts defs for new methods in DayOfWeek and Month #301
* add method params for #appendValue and #appendValueReduced #288
* add type definition for ChronoUnit.NANOS #296
* Add ZoneRulesProvider TypeScript definition #317
* Add type definition for Instant.atZone #313
### 1.10.1
* implement methods on DayOfWeek and Month #300
* Adding private constructors and abstract modifiers to TypeScript definitions #298
### 1.9.3
* fix typescript definitions: add `ZoneId#id()` #265
* fix typescript definitions: Fix DateTimeFormatter.withLocale() #277
* Remove unreachable code #278
* add package-lock for dev dependencies
### 1.9.2
#### public API
* implement atZone in Instant
* Add DateTimeParseException to typings file
### 1.9.1
#### dependency updates
* revert babel to previous version
### 1.9.0
#### public API
* add OffsetClock and add withZone and equals to other Clock impls
#### bugfixes
* fix error when parsing dates from string with e.g. WeekOfWeekbasedYear fields
* fix call to `substring` in generating error message when parsing
#### dependency updates
### 1.8.2
#### public API
* add ESM module to pkg.module build with rollup
#### dev setup
* Migrate from webpack to rollup
#### etc
* Remove usage of module.exports
#### dependency updates
### 1.7.0 1.7.1 1.8.0 1.8.1
* issues with build artifacts, dont use it.
### 1.6.3
#### public API
* improve typescript definition (see PR #196)
#### dependency updates
### etc
* Remove usage of call on constructors
### 1.6.2
#### public API
* improve typescript definition (see PR #188)
#### internal API
* add `DateTimeBuilder` to internal API
#### dependency updates
### 1.6.1
#### dependency updates
#### bugs
* fix issue #166, bug from upstream project, parse zoned date time during overlap
### 1.6.0
#### public API
* update API: export all public classes/interfaces
* add `IsoChronology#date(temporal)` function
* add export of "internal" APIs needed e.g. for plugins, these should *not* be used by users of the `js-joda` library.
Since we do not consider these a public APIs, they may change without warning!
These internal APIs are exported as the `_` object
### 1.5.5
#### bugs
* fix Period.ofDays() if called with none number string values
#### public API
* improve typescript definition
### 1.5.4
#### public API
* fail if temporals ar created with float values
* fix typescript definition and esdoc
#### dependency updates
### 1.5.2
#### public API
* fix LocalDate.now in typescript definition and esdoc
* fix LocalTime static properties in typescript definition
### 1.5.1
#### public API
* Add `use` function to typescript definition
* Add `convert` function to typescript definition
### 1.5.0
#### public API
* Add toJSON methods where missing and useful
* Remove protected class DateTimeBuilder from esdoc and typescript definition
#### lint
* add linter rules `no-var`, `prefer-const`
#### dependency updates
### 1.4.0
#### public API
* Remove private constructors, functions and classes from typescript definition (see #134)
### 1.3.1
#### public API
* Add `DateTimeFormatter.withResolverStyle` function
#### etc
* Fix DateTimeFormatterBuilder.constructor esdoc/ typescript definition
* Fix esdoc/ typescript definition for ZoneId
* Remove private functions, classses and constructors from esdoc
* unify the format pattern esdoc in `DateTimeFormatter.ofPattern`
and `DateTimeFormatterBuilder.appendPattern`, and add `u` Symbol to documentation
### 1.3.0
#### public API
* export zone/ZoneOffsetTransition
### 1.2.0
#### iana tzdb
* Complete parsing of ZoneRegions
#### etc
* Fix bower.json
* Fix LocalTime.parse esdoc/ typescript definition
#### dependency updates
### 1.1.17
#### Bugfixes
* Improve LocalDateTime.toInstant error handling
* Improve validation of LocalDate parameter values when passed as Strings
#### iana tzdb
* First quick approach for parsing ZoneRegions
### 1.1.14
#### Add more classes to public export
* add all error classes
* add zone/ZoneRules
#### code cleanup
* fix lint issues
* fix ESDoc tags
* Replace var by let/ const declaration
#### dependency updates
### 1.1.13
#### Add ZoneRulesProvider stub
Add the ZoneRulesProvider. This should be the last step to enable js-joda for an external @js-joda/timezone plugin.
#### Provide a way to extend js-joda
[Implement a use function](https://github.com/js-joda/js-joda/pull/100#issuecomment-252425196)
### Bugfixes
* Fix SystemDefaultZoneRules transition (fix a bug in convert and LocalDate.startOfDay)
### 1.1.12
#### Implement daylight saving transition functionality
Complete / implement methods/ interfaces
- LocalDate.atStartOfDayWithZone
- ZonedDateTime.ofLocal
- ZonedDateTime.ofStrict
- ZonedDateTime.withEarlierOffsetAtOverlap
- ZonedDateTime.withLaterOffsetAtOverlap
- ZonedDateTime.until
- ZoneRules
- Pseudo zones for testing purpose
Increased test coverage for zone related classes
#### Test Coverage and more threetenbp Features
increased Test Coverage by adding/extending more tests from threetenbp
but also adding own tests that increase the coverage.
This also led to missing features implemented, e.g. more Fields in `DateTimeBuilder` being handled
#### Bugfixes
fixes found by extended Tests in
- `Duration`
- `DateTimeBuilder`
- `DateTimeFormatterBuilder`
- `YearMonth`
#### dependency updates
### 1.1.11
#### Typescript typings
make typescript definitions to be module definitions (see PR #86)
#### ESDoc Updates
fixed some warnings in esdoc build regarding signature mismatches (see PR #87)
#### Bugfixes
#### dependency updates
### 1.1.9
#### Typescript typings
added initial typescript typings (`.d.ts`) provided by [@spencerwi](https://github.com/spencerwi) and test based on the code from [CheatSheet](CheatSheet.md) to verify the typings
#### Bugfixes
#### dependency updates
* several dev dependency updates
### 1.1.8
last release without a CHANGELOG.md

34
node_modules/@js-joda/core/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,34 @@
BSD License
For js-joda software
Copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* 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.
* Neither the name of js-joda 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 OWNER 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.

162
node_modules/@js-joda/core/README.md generated vendored Normal file
View File

@@ -0,0 +1,162 @@
# Immutable date and time library for JavaScript
[![npm version](https://badge.fury.io/js/%40js-joda%2Fcore.svg)](https://badge.fury.io/js/%40js-joda%2Fcore)
[![GH Actions Build Status](https://github.com/js-joda/js-joda/actions/workflows/tests.yaml/badge.svg?branch=main)](https://github.com/js-joda/js-joda/actions)
[![Sauce Test Status](https://saucelabs.com/buildstatus/js-joda)](https://saucelabs.com/u/js-joda)
[![Coverage Status](https://coveralls.io/repos/js-joda/js-joda/badge.svg?branch=main&service=github)](https://coveralls.io/github/js-joda/js-joda?branch=main)
[![Downloads/Month](https://img.shields.io/npm/dm/%40js-joda%2Fcore.svg)](https://img.shields.io/npm/dm/%40js-joda%2Fcore.svg)
[![Sauce Browser Matrix](https://saucelabs.com/browser-matrix/js-joda.svg?branch=main&42)](https://saucelabs.com/u/js-joda)
## Introduction
**js-joda** is an **immutable date and time library** for JavaScript. It provides a **simple, domain-driven and clean API** based on the ISO calendar system, which is the de facto world calendar following the proleptic Gregorian rules.
- js-joda has a lightweight footprint, only **43 kB minified and compressed**, no third party dependencies.
- js-joda is **fast**. It is about 2 to 10 times faster than other JavaScript date libraries.
- js-joda comes with built-in parsers/ formatters for ISO 8601 as specified in RFC 3339, that can be easily customized.
- js-joda supports **ECMAScript 5** browsers down to IE11.
- js-joda is a **port of the threeten** backport, which is the base for JSR-310 implementation of the Java SE 8 java.time package. Threeten is inspired by **Joda-Time**, having similar concepts and the same author.
- js-joda is **robust and stable**. We ported more then 1700 test-cases with a lots of test-permutations from the threetenbp project. We run the automated karma test-suite against Firefox, Chrome, Node and phantomjs.
## Why yet another JavaScript date and time library?
- Popular JavaScript date libraries like [moment](https://momentjs.com/) or [date-utils](https://github.com/continuouscalendar/dateutils) are **wrappers** around the native JavaScript `Date` object, providing syntactic sugar. The native `Date` object always consist of a date, time and a timezone part. In contrast, js-joda is a **standalone** date and time implementation.
- The API has a **domain-driven design** with classes for each of the different use cases, like `LocalDate`, `ZonedDateTime` or `Period`. For example, `LocalDate` allows you to handle dates without times (like birthdays or holidays) in a clean and error-safe way, especially if these dates are persisted to an external server.
- js-joda is **immutable**. Immutability aligns well with pure functions and with the architecture of frameworks like React and Flux.
## The ThreeTen domain models
### Dates and Times
- **LocalDate** represents a date without a time and timezone in the ISO-8601 calendar system, such as 2007-12-24.
- **LocalTime** represents a time without timezone in the ISO-8601 calendar system such as '11:55:00'.
- **LocalDateTime** is a description of the date (LocalDate), as used for birthdays, combined with the local time (LocalTime) as seen on a wall clock.
- **ZonedDateTime** is a date-time with a timezone in the ISO-8601 calendar system, such as 2007-12-24T16:15:30+01:00 UTC+01:00.
- **Instant** is an instantaneous point on the time-line measured from the epoch of _1970-01-01T00:00:00Z_ in epoch-seconds and nanosecond-of-second.
### Duration and Period
- **Duration** is a time-based amount of time, such as '34.5 seconds'.
- **Period** is a date-based amount of time in the ISO-8601 calendar system, such as '2 years, 3 months and 4 days'.
### Additional value types
- **Year** represents a year in the ISO-8601 calendar system, such as '2016'.
- **YearMonth** represents a year and a month in the ISO-8601 calendar system, such as '2016-01'.
- **Month** represents a month-of-year in the ISO-8601 calendar system, such as 'July'.
- **MonthDay** represents a month-day in the ISO-8601 calendar system, such as '--12-03'. Could be used to represent e.g. Birthdays.
- **DayOfWeek** represents a day-of-week in the ISO-8601 calendar system, such as 'Tuesday'.
## Getting started
### Node
Install joda using npm
```
npm install @js-joda/core
```
Then require it to any module
```js
var LocalDate = require('@js-joda/core').LocalDate;
var d = LocalDate.parse('2012-12-24').atStartOfDay().plusMonths(2); // 2013-02-24T00:00:00
```
### Browser
To use js-joda from a browser, download either `dist/js-joda.min.js` or `dist/js-joda.js` (with sourcemaps for development). Then add it as a script tag to your page
```html
<script src="js-joda.min.js"></script>
<script>
var LocalDate = JSJoda.LocalDate;
var d = LocalDate.parse('2012-12-24').atStartOfDay().plusMonths(2); // 2013-02-24T00:00:00
</script>
```
## js-joda packages
js-joda consist of four packages:
| package name | description | path |
|---|---|---|
| `@js-joda/core` | Implementation of the ThreeTen Classes and API | [/packages/core](//github.com/js-joda/js-joda/tree/main/packages/core) |
| `@js-joda/timezone` | Implementation of timezone calculation based on the iana Time Zone Database | [/packages/timezone](//github.com/js-joda/js-joda/tree/main/packages/timezone) |
| `@js-joda/locale` | Implementation of locale specific functionality for js-joda, especially for formatting and parsing locale specific dates | [/packages/locale](//github.com/js-joda/js-joda/tree/main/packages/locale) |
| `@js-joda/extra` | Implementation of the ThreeTen-Extra Classes and API |[/packages/extra](//github.com/js-joda/js-joda/tree/main/packages/extra) |
The [@js-joda/examples](//github.com/js-joda/js-joda/tree/main/packages/examples) package is for testing the different build artifacts in different context, like webpack, browser node, etc.
## Documentation
- [js-joda Quick start guide](//js-joda.github.io/js-joda/manual/getting-started.html) Quick start guide and examples
- [API](//js-joda.github.io/js-joda/identifiers.html) ESDoc generated API documentation
## Contributing
Contributions are always welcome. Before contributing please read the [code of conduct](http://contributor-covenant.org/version/1/4/) &
search the issue tracker. We use GitHub issues. Your issue may have already been discussed or fixed. To contribute, fork js-joda, commit your changes, & send a pull request.
By contributing to js-joda, you agree that your contributions will be licensed under its BSD license.
Note that only pull requests and issues that match the threeten backport API will be considered. Additional requested features will be rejected.
## License
- `js-joda` is released under the [BSD 3-clause license](//github.com/js-joda/js-joda/blob/main/LICENSE).
- `js-joda` uses the ThreeTen-Backport implementation (http://www.threeten.org/threetenbp/) as a reference base for implementation. This allows us to release js-joda under the BSD License while the OpenJDK java.time implementation is under GNU GPL+linking exception. The API of the ThreeTen-Backport is mostly identical to the official Java SE 8 API from the view of our JavaScript port.
- Our implementation reference base ThreeTen-Backport (http://www.threeten.org/threetenbp/) is also released under the BSD 3-clause license
- `OpenJDK` is under GNU GPL+linking exception.
- The author of `Joda-Time` and the lead architect of the JSR-310 is Stephen Colebourne.
The API of this project (as far as possible with JavaScript), a lot of implementation details and documentation
are just copied but never equalled.
## Roadmap
### Milestone 1: Core domains (reached with version v1.0.0)
- Support for the domain models `LocalDate`, `LocalDateTime`, `ZonedDateTime`, `Instant`, `Duration` and `Period` converting to and from ISO8601.
- `ZonedDateTime` (without support for loading iana timezone databases) currently supports only fixed offsets like UTC or UTC+02:00 and the system default time zone.
### Milestone 2: IANA timezone support (reached with version v1.2.0)
- Add IANA timezone database support to js-joda. Implement handling of daylight saving transitions, mainly in `ZonedDateTime`.
- For access to the IANA timezone database, the plugin [@js-joda/timezone](//github.com/js-joda/js-joda/tree/main/packages/timezone) is required. It provides an implementation of the [ZoneRulesProvider](//js-joda.github.io/js-joda/class/packages/core/src/zone/ZoneRulesProvider.js~ZoneRulesProvider.html) and contains the iana timezone database.
### Milestone 3: Locale support (reached with v2.0.0 of @js-joda/locale)
- Add locale support.
- Extend pattern parser/ formatter for text with locale support.
see the plugin [@js-joda/locale](//github.com/js-joda/js-joda/tree/main/packages/locale)
### Future Milestones
- Reduce library size by removing redundant code, especially by refactoring code for formatting/ parsing dates.
- Increase test coverage (ongoing task)
- Cleanup documentation (ongoing task)

10562
node_modules/@js-joda/core/dist/js-joda.cjs.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

1
node_modules/@js-joda/core/dist/js-joda.cjs.js.map generated vendored Normal file

File diff suppressed because one or more lines are too long

10504
node_modules/@js-joda/core/dist/js-joda.esm.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

1
node_modules/@js-joda/core/dist/js-joda.esm.js.map generated vendored Normal file

File diff suppressed because one or more lines are too long

10568
node_modules/@js-joda/core/dist/js-joda.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

1
node_modules/@js-joda/core/dist/js-joda.js.map generated vendored Normal file

File diff suppressed because one or more lines are too long

5
node_modules/@js-joda/core/dist/js-joda.min.js generated vendored Normal file

File diff suppressed because one or more lines are too long

51
node_modules/@js-joda/core/package.json generated vendored Normal file
View File

@@ -0,0 +1,51 @@
{
"name": "@js-joda/core",
"version": "5.6.4",
"description": "a date and time library for javascript",
"repository": {
"type": "git",
"url": "https://github.com/js-joda/js-joda.git"
},
"author": "pithu",
"contributors": [
"pithu",
"phueper"
],
"homepage": "https://js-joda.github.io/js-joda",
"license": "BSD-3-Clause",
"bugs": {
"url": "https://github.com/js-joda/js-joda/issues"
},
"main": "dist/js-joda.js",
"module": "dist/js-joda.esm.js",
"typings": "typings/js-joda.d.ts",
"files": [
"dist",
"src",
"typings",
"CHANGELOG.md",
"README.md"
],
"scripts": {
"prepublishOnly": "npm run build-dist",
"test": "NODE_ENV=test npx mocha --timeout 5000 --require @babel/register ./test/*Test_mochaOnly.js ./test/*Test.js ./test/**/*Test.js ./test/**/**/*Test.js",
"test-coverage": "NODE_ENV=test COVERAGE=1 npx nyc --report-dir=build/coverage --reporter=lcov --reporter html npx mocha --timeout 5000 --require @babel/register --reporter progress ./test/*Test.js ./test/**/*Test.js ./test/**/**/*Test.js",
"test-browser": "npx karma start --reporters=dots --single-run",
"test-saucelabs": "npx karma start --reporters=\"dots,saucelabs\" --browsers=\"sl_chrome,sl_firefox\" --single-run=true",
"test-ci": "npm run build-dist && npm run test && npm run test-browser && npm run test-ts-definitions && npm run test-coverage",
"test-ts-definitions": "TS_NODE_PROJECT='../../shared/ts-test-config.json' NODE_ENV=test mocha --timeout 5000 --require ts-node/register ./test/typescript_definitions/*.ts",
"build-dist": "npx rollup -c rollup.config.js",
"build-md-toc": "npx markdown-toc -i CheatSheet.md",
"build-gz-check": "gzip -kf dist/js-joda.min.js && ls -alh ./dist/js-joda.min.js*",
"lint": "npx eslint ."
},
"keywords": [
"date",
"time",
"timezone"
],
"nyc": {
"sourceMap": false,
"instrument": false
}
}

329
node_modules/@js-joda/core/src/Clock.js generated vendored Normal file
View File

@@ -0,0 +1,329 @@
/**
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
import { abstractMethodFail, requireNonNull } from './assert';
import { Instant } from './Instant';
import { ZoneId } from './ZoneId';
import { ZoneOffset } from './ZoneOffset';
/**
* A clock providing access to the current instant, date and time using a time-zone.
*
* Instances of this class are used to find the current instant, which can be
* interpreted using the stored time-zone to find the current date and time.
* As such, a clock can be used instead of {@link System#currentTimeMillis}
* and {@link TimeZone#getDefault}.
*
* Use of a {@link Clock} is optional. All key date-time classes also have a
* `now()` factory method that uses the system clock in the default time zone.
* The primary purpose of this abstraction is to allow alternate clocks to be
* plugged in as and when required. Applications use an object to obtain the
* current time rather than a static method. This can simplify testing.
*
* Best practice for applications is to pass a {@link Clock} into any method
* that requires the current instant.
*
* This approach allows an alternate clock, such as {@link fixed}
* or {@link offset} to be used during testing.
*
* The {@link system} factory methods provide clocks based on the best available
* system clock This may use {@link System#currentTimeMillis}, or a higher
* resolution clock if one is available.
*
* The javascript Clock implementation differs from the openjdk.
*
* Javascript only provides the UTC millis of epoch and the ZoneOffset in minutes of the system default time.
* Javascript do not provide the system default ZoneId.
*
* the system default ZoneId is only guessable by the ZoneOffset, like moment-timezone does by returning one ZoneId
* with the same ZoneOffset.
*
* Therefore we are doing a shortcut here, by defining a SystemUTCClock and a SystemDefaultClock, the Clock itself
* is returning the ZoneOffset and not the ZoneRules as in the jdk. We should change it, when introducing the iana
* timezone database and implementing the timezone domains.
*
*/
export class Clock {
/**
* Obtains a clock that returns the current instant using the
* system clock, converting to date and time using the Date.getTime() UTC millis.
*
* This clock, rather than {@link systemDefaultZone}, should be used when
* you need the current instant without the date or time.
*
* @return {Clock} a clock that uses the system clock in the UTC zone, not null
*/
static systemUTC() {
return new SystemClock(ZoneOffset.UTC);
}
/**
* Obtains a clock that returns the current instant using the best available
* system clock, converting to date and time using the default time-zone.
*
* This clock is based on the available system clock using the Date.getTime() UTC millis
*
* Using this method hard codes a dependency to the default time-zone into your application.
*
* The UTC clock (see {@link systemUTC}) should be used when you need the current instant
* without the date or time.
*
*
* @return {Clock} a clock that uses the system clock in the default zone, not null
* @see ZoneId#systemDefault()
*/
static systemDefaultZone() {
return new SystemClock(ZoneId.systemDefault());
}
/**
*
* @param {ZoneId} zone
* @return {Clock} a clock that uses the specified time zone
*/
static system(zone){
return new SystemClock(zone);
}
/**
* Obtains a clock that always returns the same instant.
*
* This clock simply returns the specified instant.
* As such, it is not a clock in the conventional sense.
* The main use case for this is in testing, where the fixed clock ensures
* tests are not dependent on the current clock.
*
* @param {Instant} fixedInstant the instant to use as the clock, not null
* @param {ZoneId} zoneId the zoneOffset to use as zone Offset, not null
* @return {Clock} a clock that always returns the same instant, not null
*/
static fixed(fixedInstant, zoneId) {
return new FixedClock(fixedInstant, zoneId);
}
/**
* Obtains a clock that returns instants from the specified clock with the
* specified duration added
* <p>
* This clock wraps another clock, returning instants that are later by the
* specified duration. If the duration is negative, the instants will be
* earlier than the current date and time.
* The main use case for this is to simulate running in the future or in the past.
* <p>
* A duration of zero would have no offsetting effect.
* Passing zero will return the underlying clock.
* <p>
* The returned implementation is immutable, thread-safe and {@code Serializable}
* providing that the base clock is.
*
* @param baseClock the base clock to add the duration to, not null
* @param duration the duration to add, not null
* @return a clock based on the base clock with the duration added, not null
*/
static offset(baseClock, duration) {
return new OffsetClock(baseClock, duration);
}
/**
* Gets the current millisecond instant of the clock.
*
* This returns the millisecond-based instant, measured from 1970-01-01T00:00Z (UTC).
* This is equivalent to the definition of {@link Date#getTime}.
*
* Most applications should avoid this method and use {@link Instant} to represent
* an instant on the time-line rather than a raw millisecond value.
* This method is provided to allow the use of the clock in high performance use cases
* where the creation of an object would be unacceptable.
*
* The default implementation currently calls {@link instant}.
*
* @return the current millisecond instant from this clock, measured from
* the Java epoch of 1970-01-01T00:00Z (UTC), not null
*/
millis(){
abstractMethodFail('Clock.millis');
}
/**
* Gets the current instant of the clock.
*
* This returns an instant representing the current instant as defined by the clock.
*
* @return {Instant} the current instant from this clock, not null
*/
instant(){
abstractMethodFail('Clock.instant');
}
zone(){
abstractMethodFail('Clock.zone');
}
/**
* Returns a copy of this clock with a different time-zone.
* <p>
* A clock will typically obtain the current instant and then convert that
* to a date or time using a time-zone. This method returns a clock with
* similar properties but using a different time-zone.
*
* @return a clock based on this clock with the specified time-zone, not null
*/
withZone(){
abstractMethodFail('Clock.withZone');
}
}
/**
* Implementation of a clock that always returns the latest time from
* {@link Date#getTime}.
*
* @private
*/
class SystemClock extends Clock {
/**
*
* @param {!ZoneId} zone
*/
constructor(zone){
requireNonNull(zone, 'zone');
super();
this._zone = zone;
}
/**
*
* @returns {!ZoneId}
*/
zone() {
return this._zone;
}
/**
*
* @returns {number}
*/
millis() {
return new Date().getTime();
}
/**
*
* @returns {Instant}
*/
instant() {
return Instant.ofEpochMilli(this.millis());
}
equals(obj) {
if (obj instanceof SystemClock) {
return this._zone.equals(obj._zone);
}
return false;
}
withZone(zone) {
if (zone.equals(this._zone)) { // intentional NPE
return this;
}
return new SystemClock(zone);
}
/**
*
* @returns {string}
*/
toString(){
return `SystemClock[${this._zone.toString()}]`;
}
}
/**
* Implementation of a clock that always returns the same instant.
* This is typically used for testing.
* @private
*/
class FixedClock extends Clock{
constructor(fixedInstant, zoneId) {
super();
this._instant = fixedInstant;
this._zoneId = zoneId;
}
instant() {
return this._instant;
}
millis(){
return this._instant.toEpochMilli();
}
zone() {
return this._zoneId;
}
toString(){
return 'FixedClock[]';
}
equals(obj) {
if (obj instanceof FixedClock) {
return this._instant.equals(obj._instant) && this._zoneId.equals(obj._zoneId);
}
return false;
}
withZone(zone) {
if (zone.equals(this._zoneId)) { // intentional NPE
return this;
}
return new FixedClock(this._instant, zone);
}
}
/**
* Implementation of a clock that adds an offset to an underlying clock.
*/
class OffsetClock extends Clock {
constructor(baseClock, offset) {
super();
this._baseClock = baseClock;
this._offset = offset;
}
zone() {
return this._baseClock.zone();
}
withZone(zone) {
if (zone.equals(this._baseClock.zone())) { // intentional NPE
return this;
}
return new OffsetClock(this._baseClock.withZone(zone), this._offset);
}
millis() {
return this._baseClock.millis() + this._offset.toMillis();
}
instant() {
return this._baseClock.instant().plus(this._offset);
}
equals(obj) {
if (obj instanceof OffsetClock) {
return this._baseClock.equals(obj._baseClock) && this._offset.equals(obj._offset);
}
return false;
}
toString() {
return `OffsetClock[${this._baseClock},${this._offset}]`;
}
}

451
node_modules/@js-joda/core/src/DayOfWeek.js generated vendored Normal file
View File

@@ -0,0 +1,451 @@
/*
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
import { DateTimeException, UnsupportedTemporalTypeException, NullPointerException } from './errors';
import { MathUtil } from './MathUtil';
import { assert, requireNonNull, requireInstance } from './assert';
import { ChronoField } from './temporal/ChronoField';
import { ChronoUnit } from './temporal/ChronoUnit';
import { IllegalArgumentException } from './errors';
import { TemporalAccessor } from './temporal/TemporalAccessor';
import { TemporalQueries } from './temporal/TemporalQueries';
import { createTemporalQuery } from './temporal/TemporalQuery';
/**
* ### Static properties of Class {@link DayOfWeek}
*
* DayOfWeek.MONDAY,
* DayOfWeek.TUESDAY,
* DayOfWeek.WEDNESDAY,
* DayOfWeek.THURSDAY,
* DayOfWeek.FRIDAY,
* DayOfWeek.SATURDAY,
* DayOfWeek.SUNDAY
*
*/
export class DayOfWeek extends TemporalAccessor {
/**
*
* @param {number} ordinal
* @param {string} name
* @private
*/
constructor(ordinal, name){
super();
this._ordinal = ordinal;
this._name = name;
}
/**
*
* @returns {number}
*/
ordinal(){
return this._ordinal;
}
/**
*
* @returns {string}
*/
name(){
return this._name;
}
/**
*
* @returns {DayOfWeek[]}
*/
static values() {
return ENUMS.slice();
}
/**
*
* @param {string} name
* @returns {DayOfWeek}
*/
static valueOf(name) {
let ordinal = 0;
for(ordinal; ordinal < ENUMS.length; ordinal++){
if(ENUMS[ordinal].name() === name){
break;
}
}
return DayOfWeek.of(ordinal+1);
}
/**
* Obtains an instance of {@link DayOfWeek} from an `int` value.
*
* {@link DayOfWeek} is an enum representing the 7 days of the week.
* This factory allows the enum to be obtained from the `int` value.
* The `int` value follows the ISO-8601 standard, from 1 (Monday) to 7 (Sunday).
*
* @param {!number} dayOfWeek the day-of-week to represent, from 1 (Monday) to 7 (Sunday)
* @return {DayOfWeek} the day-of-week singleton, not null
* @throws DateTimeException if the day-of-week is invalid
*/
static of(dayOfWeek) {
if (dayOfWeek < 1 || dayOfWeek > 7) {
throw new DateTimeException(`Invalid value for DayOfWeek: ${dayOfWeek}`);
}
return ENUMS[dayOfWeek - 1];
}
/**
* Obtains an instance of {@link DayOfWeek} from a temporal object.
*
* A {@link TemporalAccessor} represents some form of date and time information.
* This factory converts the arbitrary temporal object to an instance of {@link DayOfWeek}.
*
* The conversion extracts the {@link ChronoField#DAY_OF_WEEK} field.
*
* This method matches the signature of the functional interface {@link TemporalQuery}
* allowing it to be used as a query via method reference, {@link DayOfWeek::from}.
*
* @param {TemporalAccessor} temporal - the temporal object to convert, not null
* @return {DayOfWeek} the day-of-week, not null
* @throws DateTimeException if unable to convert to a {@link DayOfWeek}
*/
static from(temporal) {
assert(temporal != null, 'temporal', NullPointerException);
if (temporal instanceof DayOfWeek) {
return temporal;
}
try {
return DayOfWeek.of(temporal.get(ChronoField.DAY_OF_WEEK));
} catch (ex) {
if(ex instanceof DateTimeException) {
throw new DateTimeException(`Unable to obtain DayOfWeek from TemporalAccessor: ${
temporal}, type ${temporal.constructor != null ? temporal.constructor.name : ''}`, ex);
} else {
throw ex;
}
}
}
/**
* Gets the day-of-week `int` value.
*
* The values are numbered following the ISO-8601 standard, from 1 (Monday) to 7 (Sunday).
* See {@link WeekFields#dayOfWeek} for localized week-numbering.
*
* @return {number} the day-of-week, from 1 (Monday) to 7 (Sunday)
*/
value() {
return this._ordinal + 1;
}
/**
* Gets the textual representation, such as 'Mon' or 'Friday'.
*
* This returns the textual name used to identify the day-of-week.
* The parameters control the length of the returned text and the locale.
*
* If no textual mapping is found then the numeric value (see {@link getValue}) is returned.
*
* @param {TextStyle} style - the length of the text required, not null
* @param {Locale} locale - the locale to use, not null
* @return {string} the text value of the day-of-week, not null
*/
// eslint-disable-next-line no-unused-vars
displayName(style, locale) {
throw new IllegalArgumentException('Pattern using (localized) text not implemented yet!');
// return new DateTimeFormatterBuilder().appendText(ChronoField.DAY_OF_WEEK, style).toFormatter(locale).format(this);
}
/**
* Checks if the specified field is supported.
*
* This checks if this day-of-week can be queried for the specified field.
* If false, then calling the {@link range} and
* {@link get} methods will throw an exception.
*
* If the field is {@link ChronoField#DAY_OF_WEEK} then
* this method returns true.
* All other {@link ChronoField} instances will return false.
*
* If the field is not a {@link ChronoField}, then the result of this method
* is obtained by invoking `TemporalField.isSupportedBy(TemporalAccessor)`
* passing `this` as the argument.
* Whether the field is supported is determined by the field.
*
* @param {TemporalField} field - the field to check, null returns false
* @return {boolean} true if the field is supported on this day-of-week, false if not
*/
isSupported(field) {
if (field instanceof ChronoField) {
return field === ChronoField.DAY_OF_WEEK;
}
return field != null && field.isSupportedBy(this);
}
/**
* Gets the range of valid values for the specified field.
*
* The range object expresses the minimum and maximum valid values for a field.
* This day-of-week is used to enhance the accuracy of the returned range.
* If it is not possible to return the range, because the field is not supported
* or for some other reason, an exception is thrown.
*
* If the field is {@link ChronoField#DAY_OF_WEEK} then the
* range of the day-of-week, from 1 to 7, will be returned.
* All other {@link ChronoField} instances will throw a {@link DateTimeException}.
*
* If the field is not a {@link ChronoField}, then the result of this method
* is obtained by invoking `TemporalField.rangeRefinedBy(TemporalAccessor)`
* passing `this` as the argument.
* Whether the range can be obtained is determined by the field.
*
* @param {TemporalField} field - the field to query the range for, not null
* @return {ValueRange} the range of valid values for the field, not null
* @throws DateTimeException if the range for the field cannot be obtained
*/
range(field) {
if (field === ChronoField.DAY_OF_WEEK) {
return field.range();
} else if (field instanceof ChronoField) {
throw new UnsupportedTemporalTypeException(`Unsupported field: ${field}`);
}
return field.rangeRefinedBy(this);
}
/**
* Gets the value of the specified field from this day-of-week as an `int`.
*
* This queries this day-of-week for the value for the specified field.
* The returned value will always be within the valid range of values for the field.
* If it is not possible to return the value, because the field is not supported
* or for some other reason, an exception is thrown.
*
* If the field is {@link ChronoField#DAY_OF_WEEK} then the
* value of the day-of-week, from 1 to 7, will be returned.
* All other {@link ChronoField} instances will throw a {@link DateTimeException}.
*
* If the field is not a {@link ChronoField}, then the result of this method
* is obtained by invoking {@link TemporalField.getFrom}
* passing `this` as the argument. Whether the value can be obtained,
* and what the value represents, is determined by the field.
*
* @param {TemporalField} field - the field to get, not null
* @return {number} the value for the field, within the valid range of values
* @throws DateTimeException if a value for the field cannot be obtained
* @throws DateTimeException if the range of valid values for the field exceeds an `int`
* @throws DateTimeException if the value is outside the range of valid values for the field
* @throws ArithmeticException if numeric overflow occurs
*/
get(field) {
if (field === ChronoField.DAY_OF_WEEK) {
return this.value();
}
return this.range(field).checkValidIntValue(this.getLong(field), field);
}
/**
* Gets the value of the specified field from this day-of-week as a `long`.
*
* This queries this day-of-week for the value for the specified field.
* If it is not possible to return the value, because the field is not supported
* or for some other reason, an exception is thrown.
*
* If the field is {@link ChronoField#DAY_OF_WEEK} then the
* value of the day-of-week, from 1 to 7, will be returned.
* All other {@link ChronoField} instances will throw a {@link DateTimeException}.
*
* If the field is not a {@link ChronoField}, then the result of this method
* is obtained by invoking {@link TemporalField.getFrom}
* passing `this` as the argument. Whether the value can be obtained,
* and what the value represents, is determined by the field.
*
* @param {TemporalField} field - the field to get, not null
* @return {number} the value for the field
* @throws DateTimeException if a value for the field cannot be obtained
* @throws ArithmeticException if numeric overflow occurs
*/
getLong(field) {
if (field === ChronoField.DAY_OF_WEEK) {
return this.value();
} else if (field instanceof ChronoField) {
throw new UnsupportedTemporalTypeException(`Unsupported field: ${field}`);
}
return field.getFrom(this);
}
//-----------------------------------------------------------------------
/**
* Returns the day-of-week that is the specified number of days after this one.
*
* The calculation rolls around the end of the week from Sunday to Monday.
* The specified period may be negative.
*
* This instance is immutable and unaffected by this method call.
*
* @param {number} days - the days to add, positive or negative
* @return {DayOfWeek} the resulting day-of-week, not null
*/
plus(days) {
const amount = MathUtil.floorMod(days, 7);
return ENUMS[MathUtil.floorMod(this._ordinal + (amount + 7), 7)];
}
/**
* Returns the day-of-week that is the specified number of days before this one.
*
* The calculation rolls around the start of the year from Monday to Sunday.
* The specified period may be negative.
*
* This instance is immutable and unaffected by this method call.
*
* @param {number} days - the days to subtract, positive or negative
* @return {DayOfWeek} the resulting day-of-week, not null
*/
minus(days) {
return this.plus(-1 * MathUtil.floorMod(days, 7));
}
//-----------------------------------------------------------------------
/**
* Queries this day-of-week using the specified query.
*
* This queries this day-of-week using the specified query strategy object.
* The {@link TemporalQuery} object defines the logic to be used to
* obtain the result. Read the documentation of the query to understand
* what the result of this method will be.
*
* The result of this method is obtained by invoking the
* {@link TemporalQuery#queryFrom} method on the
* specified query passing `this` as the argument.
*
* @param {TemporalQuery} query the query to invoke, not null
* @return {*} the query result, null may be returned (defined by the query)
* @throws DateTimeException if unable to query (defined by the query)
* @throws ArithmeticException if numeric overflow occurs (defined by the query)
*/
query(query) {
if (query === TemporalQueries.precision()) {
return ChronoUnit.DAYS;
} else if (query === TemporalQueries.localDate() || query === TemporalQueries.localTime() || query === TemporalQueries.chronology() ||
query === TemporalQueries.zone() || query === TemporalQueries.zoneId() || query === TemporalQueries.offset()) {
return null;
}
assert(query != null, 'query', NullPointerException);
return query.queryFrom(this);
}
/**
* Adjusts the specified temporal object to have this day-of-week.
*
* This returns a temporal object of the same observable type as the input
* with the day-of-week changed to be the same as this.
*
* The adjustment is equivalent to using {@link Temporal#with}
* passing {@link ChronoField#DAY_OF_WEEK} as the field.
* Note that this adjusts forwards or backwards within a Monday to Sunday week.
* See {@link WeekFields#dayOfWeek} for localized week start days.
* See {@link TemporalAdjusters} for other adjusters
* with more control, such as `next(MONDAY)`.
*
* In most cases, it is clearer to reverse the calling pattern by using
* {@link Temporal#with}:
* <pre>
* // these two lines are equivalent, but the second approach is recommended
* temporal = thisDayOfWeek.adjustInto(temporal);
* temporal = temporal.with(thisDayOfWeek);
* </pre>
*
* For example, given a date that is a Wednesday, the following are output:
* <pre>
* dateOnWed.with(MONDAY); // two days earlier
* dateOnWed.with(TUESDAY); // one day earlier
* dateOnWed.with(WEDNESDAY); // same date
* dateOnWed.with(THURSDAY); // one day later
* dateOnWed.with(FRIDAY); // two days later
* dateOnWed.with(SATURDAY); // three days later
* dateOnWed.with(SUNDAY); // four days later
* </pre>
*
* This instance is immutable and unaffected by this method call.
*
* @param {TemporalAdjusters} temporal the target object to be adjusted, not null
* @return {Temporal} the adjusted object, not null
* @throws DateTimeException if unable to make the adjustment
* @throws ArithmeticException if numeric overflow occurs
*/
adjustInto(temporal) {
requireNonNull(temporal, 'temporal');
return temporal.with(ChronoField.DAY_OF_WEEK, this.value());
}
/**
*
* @returns {boolean}
*/
equals(other){
return this === other;
}
/**
*
* @returns {string}
*/
toString(){
return this._name;
}
/**
* Compares this DayOfWeek to another DayOfWeek.
*
* The comparison is based on the value of the DayOfWeek.
* It is "consistent with equals", as defined by {@link Comparable}.
*
* @param {DayOfWeek} other the other year to compare to, not null
* @return {number} the comparator value, negative if less, positive if greater
*/
compareTo(other) {
requireNonNull(other, 'other');
requireInstance(other, DayOfWeek, 'other');
return this._ordinal - other._ordinal;
}
/**
* toJSON() use by JSON.stringify
* delegates to toString()
*
* @return {string}
*/
toJSON() {
return this.toString();
}
}
let ENUMS;
export function _init() {
DayOfWeek.MONDAY = new DayOfWeek(0, 'MONDAY');
DayOfWeek.TUESDAY = new DayOfWeek(1, 'TUESDAY');
DayOfWeek.WEDNESDAY = new DayOfWeek(2, 'WEDNESDAY');
DayOfWeek.THURSDAY = new DayOfWeek(3, 'THURSDAY');
DayOfWeek.FRIDAY = new DayOfWeek(4, 'FRIDAY');
DayOfWeek.SATURDAY = new DayOfWeek(5, 'SATURDAY');
DayOfWeek.SUNDAY = new DayOfWeek(6, 'SUNDAY');
DayOfWeek.FROM = createTemporalQuery('DayOfWeek.FROM', (temporal) => {
return DayOfWeek.from(temporal);
});
ENUMS = [
DayOfWeek.MONDAY,
DayOfWeek.TUESDAY,
DayOfWeek.WEDNESDAY,
DayOfWeek.THURSDAY,
DayOfWeek.FRIDAY,
DayOfWeek.SATURDAY,
DayOfWeek.SUNDAY
];
}

1205
node_modules/@js-joda/core/src/Duration.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

30
node_modules/@js-joda/core/src/Enum.js generated vendored Normal file
View File

@@ -0,0 +1,30 @@
/**
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
/***
* Base class for a pseudo enum
*/
export class Enum {
constructor(name){
this._name = name;
}
equals(other){
return this === other;
}
toString() {
return this._name;
}
/**
* toJSON() use by JSON.stringify
* delegates to toString()
*
* @return {string}
*/
toJSON() {
return this.toString();
}
}

1019
node_modules/@js-joda/core/src/Instant.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

1681
node_modules/@js-joda/core/src/LocalDate.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

1643
node_modules/@js-joda/core/src/LocalDateTime.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

1370
node_modules/@js-joda/core/src/LocalTime.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

240
node_modules/@js-joda/core/src/MathUtil.js generated vendored Normal file
View File

@@ -0,0 +1,240 @@
/**
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
import { ArithmeticException } from './errors';
export const MAX_SAFE_INTEGER = 9007199254740991;
export const MIN_SAFE_INTEGER = -9007199254740991;
/**
* Math helper with static function for integer operations
*/
export class MathUtil {
/**
*
* @param {number} x
* @param {number} y
* @returns {number}
*/
static intDiv(x, y) {
let r = x/y;
r = MathUtil.roundDown(r);
return MathUtil.safeZero(r);
}
/**
*
* @param {number} x
* @param {number} y
* @returns {number}
*/
static intMod(x, y) {
let r = x - MathUtil.intDiv(x, y) * y;
r = MathUtil.roundDown(r);
return MathUtil.safeZero(r);
}
/**
*
* @param {number} r
* @returns {number}
*/
static roundDown(r){
if (r < 0) {
return Math.ceil(r);
} else {
return Math.floor(r);
}
}
/**
*
* @param {number} x
* @param {number} y
* @returns {number}
*/
static floorDiv(x, y){
const r = Math.floor(x / y);
return MathUtil.safeZero(r);
}
/**
*
* @param {number} x
* @param {number} y
* @returns {number}
*/
static floorMod(x, y){
const r = x - MathUtil.floorDiv(x, y) * y;
return MathUtil.safeZero(r);
}
/**
*
* @param {number} x
* @param {number} y
* @returns {number}
*/
static safeAdd(x, y) {
MathUtil.verifyInt(x);
MathUtil.verifyInt(y);
if (x === 0) {
return MathUtil.safeZero(y);
}
if (y === 0) {
return MathUtil.safeZero(x);
}
const r = MathUtil.safeToInt(x + y);
if (r === x || r === y) {
throw new ArithmeticException('Invalid addition beyond MAX_SAFE_INTEGER!');
}
return r;
}
/**
*
* @param {number} x
* @param {number} y
* @returns {number}
*/
static safeSubtract(x, y) {
MathUtil.verifyInt(x);
MathUtil.verifyInt(y);
if (x === 0 && y === 0) {
return 0;
} else if (x === 0) {
return MathUtil.safeZero(-1 * y);
} else if (y === 0) {
return MathUtil.safeZero(x);
}
return MathUtil.safeToInt(x - y);
}
/**
*
* @param {number} x
* @param {number} y
* @returns {number}
*/
static safeMultiply(x, y) {
MathUtil.verifyInt(x);
MathUtil.verifyInt(y);
if (x === 1) {
return MathUtil.safeZero(y);
}
if (y === 1) {
return MathUtil.safeZero(x);
}
if (x === 0 || y === 0) {
return 0;
}
const r = MathUtil.safeToInt(x * y);
if (r / y !== x || (x === MIN_SAFE_INTEGER && y === -1) || (y === MIN_SAFE_INTEGER && x === -1)) {
throw new ArithmeticException(`Multiplication overflows: ${x} * ${y}`);
}
return r;
}
/**
*
* @param {number} value
* @returns {number}
*/
static parseInt(value) {
const r = parseInt(value);
return MathUtil.safeToInt(r);
}
/**
*
* @param {number} value
* @returns {number}
*/
static safeToInt(value) {
MathUtil.verifyInt(value);
return MathUtil.safeZero(value);
}
/**
*
* @param {number} value
*/
static verifyInt(value){
if (value == null) {
throw new ArithmeticException(`Invalid value: '${value}', using null or undefined as argument`);
}
if (isNaN(value)) {
throw new ArithmeticException('Invalid int value, using NaN as argument');
}
if (Number.isInteger) {
if (!Number.isInteger(Number(value))) {
throw new ArithmeticException(`Invalid value: '${value}' is a float`);
}
} else if ((value % 1) !== 0) { // IE11 does not support Number.isInteger
throw new ArithmeticException(`Invalid value: '${value}' is a float`);
}
if (value > MAX_SAFE_INTEGER || value < MIN_SAFE_INTEGER) {
throw new ArithmeticException(`Calculation overflows an int: ${value}`);
}
}
/**
* convert -0 to 0 and int as string to a number ( '1' -> 1 )
*
* @param {number} value
* @returns {number}
*/
static safeZero(value){
return value === 0 ? 0 : +value;
}
/**
* Compares two Numbers.
*
* @param {number} a the first value
* @param {number} b the second value
* @return {number} the result
*/
static compareNumbers(a, b) {
if (a < b) {
return -1;
}
if (a > b) {
return 1;
}
return 0;
}
// convert to small integer for v8 optimisation
static smi(int) {
return ((int >>> 1) & 0x40000000) | (int & 0xBFFFFFFF);
}
// calculate 32 bit hash of a number and convert to SMI
static hash(number) {
if (number !== number || number === Infinity) {
return 0;
}
let result = number;
while (number > 0xFFFFFFFF) {
number /= 0xFFFFFFFF;
result ^= number;
}
return MathUtil.smi(result);
}
// default hashCode calculation for a number sequence as mentioned by Joshua Bloch
static hashCode(...numbers) {
let result = 17;
for (const n of numbers) {
result = (result << 5) - result + MathUtil.hash(n);
}
return MathUtil.hash(result);
}
}
MathUtil.MAX_SAFE_INTEGER = MAX_SAFE_INTEGER;
MathUtil.MIN_SAFE_INTEGER = MIN_SAFE_INTEGER;

600
node_modules/@js-joda/core/src/Month.js generated vendored Normal file
View File

@@ -0,0 +1,600 @@
/**
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
import { assert, requireNonNull, requireInstance } from './assert';
import { MathUtil } from './MathUtil';
import { ChronoField } from './temporal/ChronoField';
import { ChronoUnit } from './temporal/ChronoUnit';
import { DateTimeException, IllegalArgumentException, UnsupportedTemporalTypeException } from './errors';
import { IsoChronology } from './chrono/IsoChronology';
import { TemporalAccessor } from './temporal/TemporalAccessor';
import { TemporalQueries } from './temporal/TemporalQueries';
/**
* A month-of-year, such as 'July'.
*
* {@link Month} is representing the 12 months of the year -
* January, February, March, April, May, June, July, August, September, October,
* November and December.
*
* In addition to the textual name, each month-of-year has an `int` value.
* The `int` value follows normal usage and the ISO-8601 standard,
* from 1 (January) to 12 (December). It is recommended that applications use the static values defined by this class
* rather than the `int` value to ensure code clarity.
*
* This class represents a common concept that is found in many calendar systems.
* As such, this class may be used by any calendar system that has the month-of-year
* concept defined exactly equivalent to the ISO-8601 calendar system.
*
* ### Static properties of Class {@link Month}
*
* Month.JANUARY, Month.FEBRUARY, Month.MARCH, Month.APRIL, Month.MAY, Month.JUNE,
* Month.JULY, Month.AUGUST, Month.SEPTEMBER, Month.OCTOBER, Month.NOVEMBER, Month.DECEMBER
*
*/
export class Month extends TemporalAccessor {
/**
*
* @param {number} ordinal
* @param {string} name
* @private
*/
constructor(value, name){
super();
this._value = MathUtil.safeToInt(value);
this._name = name;
}
/**
*
* @return {number} gets the value
*/
value() {
return this._value;
}
/**
*
* @returns {number}
*/
ordinal(){
return this._value - 1;
}
/**
*
* @returns {string}
*/
name(){
return this._name;
}
/**
* Gets the textual representation, such as 'Jan' or 'December'.
*
* This returns the textual name used to identify the month-of-year.
* The parameters control the length of the returned text and the locale.
*
* If no textual mapping is found then the numeric value (see {@link getValue}) is returned.
*
* @param {TextStyle} style - the length of the text required, not null
* @param {Locale} locale - the locale to use, not null
* @return {string} the text value of the day-of-week, not null
*/
// eslint-disable-next-line no-unused-vars
displayName(style, locale) {
// TODO:
throw new IllegalArgumentException('Pattern using (localized) text not implemented yet!');
}
/**
* Checks if the specified field is supported.
*
* This checks if this month-of-year can be queried for the specified field.
* If false, then calling the range (see {@link range}) and
* get (see {@link get}) methods will throw an exception.
*
* If the field is MONTH_OF_YEAR (see {@link ChronoField#MONTH_OF_YEAR}) then
* this method returns true.
* All other {@link ChronoField} instances will return false.
*
* If the field is not a {@link ChronoField}, then the result of this method
* is obtained by invoking {@link TemporalField.isSupportedBy}
* passing `this` as the argument.
* Whether the field is supported is determined by the field.
*
* @param {TemporalField} field - the field to check, null returns false
* @return {boolean} true if the field is supported on this month-of-year, false if not
*/
isSupported(field) {
if (null === field) {
return false;
}
if (field instanceof ChronoField) {
return field === ChronoField.MONTH_OF_YEAR;
}
return field != null && field.isSupportedBy(this);
}
/**
* Gets the value of the specified field from this month-of-year as an `int`.
*
* This queries this month for the value of the specified field.
* The returned value will always be within the valid range of values for the field.
* If it is not possible to return the value, because the field is not supported
* or for some other reason, an exception is thrown.
*
* If the field is MONTH_OF_YEAR (see {@link ChronoField#MONTH_OF_YEAR}) then the
* value of the month-of-year, from 1 to 12, will be returned.
* All other {@link ChronoField} instances will throw an {@link UnsupportedTemporalTypeException}.
*
* If the field is not a {@link ChronoField}, then the result of this method
* is obtained by invoking {@link TemporalField.getFrom}
* passing `this` as the argument. Whether the value can be obtained,
* and what the value represents, is determined by the field.
*
* @param {TemporalField} field - the field to get, not null
* @return {Number} the value for the field, within the valid range of values
* @throws DateTimeException if a value for the field cannot be obtained or
* the value is outside the range of valid values for the field
* @throws UnsupportedTemporalTypeException if the field is not supported or
* the range of values exceeds an `int`
* @throws ArithmeticException if numeric overflow occurs
*/
get(field) {
if (field === ChronoField.MONTH_OF_YEAR) {
return this.value();
}
return this.range(field).checkValidIntValue(this.getLong(field), field);
}
/**
* Gets the value of the specified field from this month-of-year as a `long`.
*
* This queries this month for the value of the specified field.
* If it is not possible to return the value, because the field is not supported
* or for some other reason, an exception is thrown.
*
* If the field is MONTH_OF_YEAR (see {@link ChronoField#MONTH_OF_YEAR}) then the
* value of the month-of-year, from 1 to 12, will be returned.
* All other {@link ChronoField} instances will throw an {@link UnsupportedTemporalTypeException}.
*
* If the field is not a {@link ChronoField}, then the result of this method
* is obtained by invoking {@link TemporalField.getFrom}
* passing `this` as the argument. Whether the value can be obtained,
* and what the value represents, is determined by the field.
*
* @param {TemporalField} field - the field to get, not null
* @return {Number} the value for the field
* @throws DateTimeException if a value for the field cannot be obtained
* @throws UnsupportedTemporalTypeException if the field is not supported
* @throws ArithmeticException if numeric overflow occurs
*/
getLong(field) {
if (field === ChronoField.MONTH_OF_YEAR) {
return this.value();
} else if (field instanceof ChronoField) {
throw new UnsupportedTemporalTypeException(`Unsupported field: ${field}`);
}
return field.getFrom(this);
}
/**
* Returns the month-of-year that is the specified number of months after this one.
*
* The calculation rolls around the end of the year from December to January.
* The specified period may be negative.
*
* This instance is immutable and unaffected by this method call.
*
* @param {number} months - the months to add, positive or negative
* @return {Month} the resulting month, not null
*/
plus(months) {
const amount = MathUtil.intMod(months, 12) + 12; // + 12 to make sure negative arguments are positive, the total is "corrected" by the next % 12
let newMonthVal = MathUtil.intMod((this.value() + amount), 12);
/* December is 12, not 0, but 12 % 12 = 0 */
newMonthVal = newMonthVal === 0 ? 12 : newMonthVal;
return Month.of(newMonthVal);
}
/**
* Returns the month-of-year that is the specified number of months before this one.
*
* The calculation rolls around the start of the year from January to December.
* The specified period may be negative.
*
* This instance is immutable and unaffected by this method call.
*
* @param {number} months - the months to subtract, positive or negative
* @return {Month} the resulting month, not null
*/
minus(months) {
return this.plus(-1 * MathUtil.intMod(months, 12));
}
/**
* Gets the length of this month in days.
*
* This takes a flag to determine whether to return the length for a leap year or not.
*
* February has 28 days in a standard year and 29 days in a leap year.
* April, June, September and November have 30 days.
* All other months have 31 days.
*
* @param {boolean} leapYear - true if the length is required for a leap year
* @return {number} the length of this month in days, from 28 to 31
*/
length(leapYear) {
switch (this) {
case Month.FEBRUARY:
return (leapYear ? 29 : 28);
case Month.APRIL:
case Month.JUNE:
case Month.SEPTEMBER:
case Month.NOVEMBER:
return 30;
default:
return 31;
}
}
/**
* Gets the minimum length of this month in days.
*
* February has a minimum length of 28 days.
* April, June, September and November have 30 days.
* All other months have 31 days.
*
* @return {number} the minimum length of this month in days, from 28 to 31
*/
minLength() {
switch (this) {
case Month.FEBRUARY:
return 28;
case Month.APRIL:
case Month.JUNE:
case Month.SEPTEMBER:
case Month.NOVEMBER:
return 30;
default:
return 31;
}
}
/**
* Gets the maximum length of this month in days.
*
* February has a maximum length of 29 days.
* April, June, September and November have 30 days.
* All other months have 31 days.
*
* @return {number} the maximum length of this month in days, from 29 to 31
*/
maxLength() {
switch (this) {
case Month.FEBRUARY:
return 29;
case Month.APRIL:
case Month.JUNE:
case Month.SEPTEMBER:
case Month.NOVEMBER:
return 30;
default:
return 31;
}
}
/**
* Gets the day-of-year corresponding to the first day of this month.
*
* This returns the day-of-year that this month begins on, using the leap
* year flag to determine the length of February.
*
* @param {boolean} leapYear - true if the length is required for a leap year
* @return {number} the day of year corresponding to the first day of this month, from 1 to 336
*/
firstDayOfYear(leapYear) {
const leap = leapYear ? 1 : 0;
switch (this) {
case Month.JANUARY:
return 1;
case Month.FEBRUARY:
return 32;
case Month.MARCH:
return 60 + leap;
case Month.APRIL:
return 91 + leap;
case Month.MAY:
return 121 + leap;
case Month.JUNE:
return 152 + leap;
case Month.JULY:
return 182 + leap;
case Month.AUGUST:
return 213 + leap;
case Month.SEPTEMBER:
return 244 + leap;
case Month.OCTOBER:
return 274 + leap;
case Month.NOVEMBER:
return 305 + leap;
case Month.DECEMBER:
default:
return 335 + leap;
}
}
/**
* Gets the month corresponding to the first month of this quarter.
*
* The year can be divided into four quarters.
* This method returns the first month of the quarter for the base month.
* January, February and March return January.
* April, May and June return April.
* July, August and September return July.
* October, November and December return October.
*
* @return {Month} the first month of the quarter corresponding to this month, not null
*/
firstMonthOfQuarter() {
switch (this) {
case Month.JANUARY:
case Month.FEBRUARY:
case Month.MARCH:
return Month.JANUARY;
case Month.APRIL:
case Month.MAY:
case Month.JUNE:
return Month.APRIL;
case Month.JULY:
case Month.AUGUST:
case Month.SEPTEMBER:
return Month.JULY;
case Month.OCTOBER:
case Month.NOVEMBER:
case Month.DECEMBER:
default:
return Month.OCTOBER;
}
}
/**
* Queries this month-of-year using the specified query.
*
* This queries this month-of-year using the specified query strategy object.
* The {@link TemporalQuery} object defines the logic to be used to
* obtain the result. Read the documentation of the query to understand
* what the result of this method will be.
*
* The result of this method is obtained by invoking the
* {@link TemporalQuery#queryFrom} method on the
* specified query passing `this` as the argument.
*
* @param {TemporalQuery} query - the query to invoke, not null
* @return {*} the query result, null may be returned (defined by the query)
* @throws DateTimeException if unable to query (defined by the query)
* @throws ArithmeticException if numeric overflow occurs (defined by the query)
*/
query(query) {
assert(query != null, 'query() parameter must not be null', DateTimeException);
if (query === TemporalQueries.chronology()) {
return IsoChronology.INSTANCE;
} else if (query === TemporalQueries.precision()) {
return ChronoUnit.MONTHS;
}
return super.query(query);
}
/**
* toString implementation... in JDK this is inherited from the Enum class
*
* @return {String}
*/
toString() {
switch (this) {
case Month.JANUARY:
return 'JANUARY';
case Month.FEBRUARY:
return 'FEBRUARY';
case Month.MARCH:
return 'MARCH';
case Month.APRIL:
return 'APRIL';
case Month.MAY:
return 'MAY';
case Month.JUNE:
return 'JUNE';
case Month.JULY:
return 'JULY';
case Month.AUGUST:
return 'AUGUST';
case Month.SEPTEMBER:
return 'SEPTEMBER';
case Month.OCTOBER:
return 'OCTOBER';
case Month.NOVEMBER:
return 'NOVEMBER';
case Month.DECEMBER:
return 'DECEMBER';
default:
return `unknown Month, value: ${this.value()}`;
}
}
/**
* toJSON() use by JSON.stringify
* delegates to toString()
*
* @return {string}
*/
toJSON() {
return this.toString();
}
/**
* Adjusts the specified temporal object to have this month-of-year.
*
* This returns a temporal object of the same observable type as the input
* with the month-of-year changed to be the same as this.
*
* The adjustment is equivalent to using {@link Temporal#with}
* passing {@link ChronoField#MONTH_OF_YEAR} as the field.
* If the specified temporal object does not use the ISO calendar system then
* a {@link DateTimeException} is thrown.
*
* In most cases, it is clearer to reverse the calling pattern by using
* {@link Temporal#with}:
* <pre>
* // these two lines are equivalent, but the second approach is recommended
* temporal = thisMonth.adjustInto(temporal);
* temporal = temporal.with(thisMonth);
* </pre>
*
* For example, given a date in May, the following are output:
* <pre>
* dateInMay.with(JANUARY); // four months earlier
* dateInMay.with(APRIL); // one months earlier
* dateInMay.with(MAY); // same date
* dateInMay.with(JUNE); // one month later
* dateInMay.with(DECEMBER); // seven months later
* </pre>
*
* This instance is immutable and unaffected by this method call.
*
* @param {Temporal} temporal - the target object to be adjusted, not null
* @return {Temporal} the adjusted object, not null
* @throws DateTimeException if unable to make the adjustment
* @throws ArithmeticException if numeric overflow occurs
*/
adjustInto(temporal) {
/* we support only ISO for now
if (Chronology.from(temporal).equals(IsoChronology.INSTANCE) === false) {
throw new DateTimeException('Adjustment only supported on ISO date-time');
}
*/
return temporal.with(ChronoField.MONTH_OF_YEAR, this.value());
}
/**
* Compares this Month to another Month.
*
* The comparison is based on the value of the Month.
* It is "consistent with equals", as defined by {@link Comparable}.
*
* @param {Month} other the other year to compare to, not null
* @return {number} the comparator value, negative if less, positive if greater
*/
compareTo(other) {
requireNonNull(other, 'other');
requireInstance(other, Month, 'other');
return this._value - other._value;
}
/**
*
* @returns {boolean}
*/
equals(other){
return this === other;
}
/**
*
* @param {string} name
* @returns {Month}
*/
static valueOf(name) {
let ordinal = 0;
for(ordinal; ordinal < MONTHS.length; ordinal++){
if(MONTHS[ordinal].name() === name){
break;
}
}
return Month.of(ordinal+1);
}
/**
* replacement for enum values
* @return {Month[]}
*/
static values(){
return MONTHS.slice();
}
/**
*
* @param {number} month
* @return {Month} not null
**/
static of(month) {
if (month < 1 || month > 12) {
assert(false, `Invalid value for MonthOfYear: ${month}`, DateTimeException);
}
return MONTHS[month-1];
}
/**
* Obtains an instance of {@link Month} from a temporal object.
*
* This obtains a month based on the specified temporal.
* A {@link TemporalAccessor} represents an arbitrary set of date and time information,
* which this factory converts to an instance of {@link Month}.
*
* The conversion extracts the MONTH_OF_YEAR (see {@link ChronoField#MONTH_OF_YEAR}) field.
* The extraction is only permitted if the temporal object has an ISO
* chronology, or can be converted to a {@link LocalDate}.
*
* This method matches the signature of the functional interface {@link TemporalQuery}
* allowing it to be used in queries via method reference, {@link Month::from}.
*
* @param {TemporalAccessor} temporal the temporal object to convert, not null
* @return {Month} the month-of-year, not null
* @throws DateTimeException if unable to convert to a {@link Month}
*/
static from(temporal) {
if (temporal instanceof Month) {
return temporal;
}
try {
/* only ISO for now
if (IsoChronology.INSTANCE.equals(Chronology.from(temporal)) == false) {
temporal = LocalDate.from(temporal);
}*/
return Month.of(temporal.get(ChronoField.MONTH_OF_YEAR));
} catch (ex) {
throw new DateTimeException(`Unable to obtain Month from TemporalAccessor: ${
temporal} of type ${temporal && temporal.constructor != null ? temporal.constructor.name : ''}`, ex);
}
}
}
let MONTHS;
export function _init() {
Month.JANUARY = new Month(1, 'JANUARY');
Month.FEBRUARY = new Month(2, 'FEBRUARY');
Month.MARCH = new Month(3, 'MARCH');
Month.APRIL = new Month(4, 'APRIL');
Month.MAY = new Month(5, 'MAY');
Month.JUNE = new Month(6, 'JUNE');
Month.JULY = new Month(7, 'JULY');
Month.AUGUST = new Month(8, 'AUGUST');
Month.SEPTEMBER = new Month(9, 'SEPTEMBER');
Month.OCTOBER = new Month(10, 'OCTOBER');
Month.NOVEMBER = new Month(11, 'NOVEMBER');
Month.DECEMBER = new Month(12, 'DECEMBER');
MONTHS = [
Month.JANUARY, Month.FEBRUARY, Month.MARCH, Month.APRIL, Month.MAY, Month.JUNE,
Month.JULY, Month.AUGUST, Month.SEPTEMBER, Month.OCTOBER, Month.NOVEMBER, Month.DECEMBER
];
}

730
node_modules/@js-joda/core/src/MonthDay.js generated vendored Normal file
View File

@@ -0,0 +1,730 @@
/*
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @license BSD-3-Clause (see LICENSE.md in the root directory of this source tree)
*/
import { requireNonNull, requireInstance } from './assert';
import { DateTimeException, UnsupportedTemporalTypeException } from './errors';
import { MathUtil } from './MathUtil';
import { ChronoField } from './temporal/ChronoField';
import { Clock } from './Clock';
import { DateTimeFormatter } from './format/DateTimeFormatter';
import { DateTimeFormatterBuilder } from './format/DateTimeFormatterBuilder';
import { IsoChronology } from './chrono/IsoChronology';
import { LocalDate } from './LocalDate';
import { Month } from './Month';
import { TemporalAccessor } from './temporal/TemporalAccessor';
import { TemporalQuery, createTemporalQuery } from './temporal/TemporalQuery';
import { TemporalQueries } from './temporal/TemporalQueries';
import { ValueRange } from './temporal/ValueRange';
import { Year } from './Year';
import { ZoneId } from './ZoneId';
/**
* A month-day in the ISO-8601 calendar system, such as `--12-03`.
*
* {@link MonthDay} is an immutable date-time object that represents the combination
* of a year and month. Any field that can be derived from a month and day, such as
* quarter-of-year, can be obtained.
*
* This class does not store or represent a year, time or time-zone.
* For example, the value "December 3rd" can be stored in a {@link MonthDay}.
*
* Since a {@link MonthDay} does not possess a year, the leap day of
* February 29th is considered valid.
*
* This class implements {@link TemporalAccessor} rather than {@link Temporal}.
* This is because it is not possible to define whether February 29th is valid or not
* without external information, preventing the implementation of plus/minus.
* Related to this, {@link MonthDay} only provides access to query and set the fields
* {@link MONTH_OF_YEAR} and {@link DAY_OF_MONTH}.
*
* The ISO-8601 calendar system is the modern civil calendar system used today
* in most of the world. It is equivalent to the proleptic Gregorian calendar
* system, in which today's rules for leap years are applied for all time.
* For most applications written today, the ISO-8601 rules are entirely suitable.
* However, any application that makes use of historical dates, and requires them
* to be accurate will find the ISO-8601 approach unsuitable.
*
* ### Specification for implementors
*
* This class is immutable and thread-safe.
*/
export class MonthDay extends TemporalAccessor {
/**
* function overloading for {@link MonthDay.now}
*
* if called with 0 argument {@link MonthDay.now0} is executed,
*
* if called with 1 argument and first argument is an instance of ZoneId, then {@link MonthDay.nowZoneId} is executed,
*
* otherwise {@link MonthDay.nowClock} is executed
*
* @param {?(ZoneId|Clock)} zoneIdOrClock
* @returns {MonthDay}
*/
static now(zoneIdOrClock) {
if (arguments.length === 0) {
return MonthDay.now0();
} else if (arguments.length === 1 && zoneIdOrClock instanceof ZoneId) {
return MonthDay.nowZoneId(zoneIdOrClock);
} else {
return MonthDay.nowClock(zoneIdOrClock);
}
}
/**
* Obtains the current month-day from the system clock in the default time-zone.
*
* This will query the system clock (see {@link Clock#systemDefaultZone}) in the default
* time-zone to obtain the current month-day.
*
* Using this method will prevent the ability to use an alternate clock for testing
* because the clock is hard-coded.
*
* @return {MonthDay} the current month-day using the system clock and default time-zone, not null
*/
static now0() {
return this.nowClock(Clock.systemDefaultZone());
}
/**
* Obtains the current month-day from the system clock in the specified time-zone.
*
* This will query the system clock (see {@link Clock#system}) to obtain the current month-day.
* Specifying the time-zone avoids dependence on the default time-zone.
*
* Using this method will prevent the ability to use an alternate clock for testing
* because the clock is hard-coded.
*
* @param {ZoneId} zone the zone ID to use, not null
* @return {MonthDay} the current month-day using the system clock, not null
*/
static nowZoneId(zone) {
requireNonNull(zone, 'zone');
return this.nowClock(Clock.system(zone));
}
/**
* Obtains the current month-day from the specified clock.
*
* This will query the specified clock to obtain the current month-day.
* Using this method allows the use of an alternate clock for testing.
* The alternate clock may be introduced using dependency injection (see {@link Clock}).
*
* @param {Clock} clock the clock to use, not null
* @return {MonthDay} the current month-day, not null
*/
static nowClock(clock) {
requireNonNull(clock, 'clock');
const now = LocalDate.now(clock); // called once
return MonthDay.of(now.month(), now.dayOfMonth());
}
//-----------------------------------------------------------------------
/**
* function overloading for {@link MonthDay.of}
*
* if called with 2 argument and first argument is an instance of Month, then {@link MonthDay.ofMonthNumber} is executed,
*
* otherwise {@link MonthDay.ofNumberNumber} is executed
*
* @param {!(Month|number)} monthOrNumber
* @param {?number} number
* @returns {MonthDay}
*/
static of(monthOrNumber, number) {
if (arguments.length === 2 && monthOrNumber instanceof Month) {
return MonthDay.ofMonthNumber(monthOrNumber, number);
} else {
return MonthDay.ofNumberNumber(monthOrNumber, number);
}
}
/**
* Obtains an instance of {@link MonthDay}.
*
* The day-of-month must be valid for the month within a leap year.
* Hence, for February, day 29 is valid.
*
* For example, passing in April and day 31 will throw an exception, as
* there can never be April 31st in any year. By contrast, passing in
* February 29th is permitted, as that month-day can sometimes be valid.
*
* @param {Month} month the month-of-year to represent, not null
* @param {number} dayOfMonth the day-of-month to represent, from 1 to 31
* @return {MonthDay} the month-day, not null
* @throws DateTimeException if the value of any field is out of range
* @throws DateTimeException if the day-of-month is invalid for the month
*/
static ofMonthNumber(month, dayOfMonth) {
requireNonNull(month, 'month');
ChronoField.DAY_OF_MONTH.checkValidValue(dayOfMonth);
if (dayOfMonth > month.maxLength()) {
throw new DateTimeException(`Illegal value for DayOfMonth field, value ${dayOfMonth
} is not valid for month ${month.toString()}`);
}
return new MonthDay(month.value(), dayOfMonth);
}
/**
* Obtains an instance of {@link MonthDay}.
*
* The day-of-month must be valid for the month within a leap year.
* Hence, for month 2 (February), day 29 is valid.
*
* For example, passing in month 4 (April) and day 31 will throw an exception, as
* there can never be April 31st in any year. By contrast, passing in
* February 29th is permitted, as that month-day can sometimes be valid.
*
* @param {number} month the month-of-year to represent, from 1 (January) to 12 (December)
* @param {number} dayOfMonth the day-of-month to represent, from 1 to 31
* @return {MonthDay} the month-day, not null
* @throws DateTimeException if the value of any field is out of range
* @throws DateTimeException if the day-of-month is invalid for the month
*/
static ofNumberNumber(month, dayOfMonth) {
requireNonNull(month, 'month');
requireNonNull(dayOfMonth, 'dayOfMonth');
return MonthDay.of(Month.of(month), dayOfMonth);
}
//-----------------------------------------------------------------------
/**
* Obtains an instance of {@link MonthDay} from a temporal object.
*
* A {@link TemporalAccessor} represents some form of date and time information.
* This factory converts the arbitrary temporal object to an instance of {@link MonthDay}.
*
* The conversion extracts the MONTH_OF_YEAR (see {@link ChronoField#MONTH_OF_YEAR}) and
* DAY_OF_MONTH (see {@link ChronoField#DAY_OF_MONTH}) fields.
* The extraction is only permitted if the date-time has an ISO chronology.
*
* This method matches the signature of the functional interface {@link TemporalQuery}
* allowing it to be used in queries via method reference, {@link MonthDay::from}.
*
* @param {TemporalAccessor} temporal the temporal object to convert, not null
* @return {MonthDay} the month-day, not null
* @throws DateTimeException if unable to convert to a {@link MonthDay}
*/
static from(temporal) {
requireNonNull(temporal, 'temporal');
requireInstance(temporal, TemporalAccessor, 'temporal');
if (temporal instanceof MonthDay) {
return temporal;
}
try {
/* TODO: only IsoChronology for now
if (IsoChronology.INSTANCE.equals(Chronology.from(temporal)) == false) {
temporal = LocalDate.from(temporal);
}*/
return MonthDay.of(temporal.get(ChronoField.MONTH_OF_YEAR), temporal.get(ChronoField.DAY_OF_MONTH));
} catch (ex) {
throw new DateTimeException(`Unable to obtain MonthDay from TemporalAccessor: ${
temporal}, type ${temporal && temporal.constructor != null ? temporal.constructor.name : ''}`);
}
}
//-----------------------------------------------------------------------
/**
* function overloading for {@link MonthDay.parse}
*
* if called with 1 argument, then {@link MonthDay.parseString} is executed,
*
* otherwise {@link MonthDay.parseStringFormatter} is executed
*
* @param {!(String)} text
* @param {?DateTimeFormatter} formatter
* @returns {MonthDay}
*/
static parse(text, formatter) {
if (arguments.length === 1) {
return MonthDay.parseString(text);
} else {
return MonthDay.parseStringFormatter(text, formatter);
}
}
/**
* Obtains an instance of {@link MonthDay} from a text string such as `--12-03`.
*
* The string must represent a valid month-day.
* The format is `--MM-dd`.
*
* @param {String} text the text to parse such as "--12-03", not null
* @return {MonthDay} the parsed month-day, not null
* @throws DateTimeParseException if the text cannot be parsed
*/
static parseString(text) {
return MonthDay.parseStringFormatter(text, PARSER);
}
/**
* Obtains an instance of {@link MonthDay} from a text string using a specific formatter.
*
* The text is parsed using the formatter, returning a month-day.
*
* @param {String} text the text to parse, not null
* @param {DateTimeFormatter} formatter the formatter to use, not null
* @return {MonthDay} the parsed month-day, not null
* @throws DateTimeParseException if the text cannot be parsed
*/
static parseStringFormatter(text, formatter) {
requireNonNull(text, 'text');
requireNonNull(formatter, 'formatter');
requireInstance(formatter, DateTimeFormatter, 'formatter');
return formatter.parse(text, MonthDay.FROM);
}
//-----------------------------------------------------------------------
/**
* Constructor, previously validated.
*
* @param {number} month the month-of-year to represent, validated from 1 to 12
* @param {number} dayOfMonth the day-of-month to represent, validated from 1 to 29-31
* @private
*/
constructor(month, dayOfMonth) {
super();
this._month = MathUtil.safeToInt(month);
this._day = MathUtil.safeToInt(dayOfMonth);
}
//-----------------------------------------------------------------------
/**
* Gets the month-of-year field from 1 to 12.
*
* This method returns the month as an `int` from 1 to 12.
* Application code is frequently clearer if the enum {@link Month}
* is used by calling {@link getMonth}.
*
* @return {number} the month-of-year, from 1 to 12
* @see #month()
*/
monthValue() {
return this._month;
}
/**
* Gets the month-of-year field using the {@link Month} enum.
*
* This method returns the enum {@link Month} for the month.
* This avoids confusion as to what `int` values mean.
* If you need access to the primitive `int` value then the enum
* provides the int value (see {@link Month#getValue}).
*
* @return {Month} the month-of-year, not null
* @see #getMonthValue()
*/
month() {
return Month.of(this._month);
}
/**
* Gets the day-of-month field.
*
* This method returns the primitive `int` value for the day-of-month.
*
* @return {number} the day-of-month, from 1 to 31
*/
dayOfMonth() {
return this._day;
}
//-----------------------------------------------------------------------
/**
* Checks if the specified field is supported.
*
* This checks if this month-day can be queried for the specified field.
* If false, then calling the range (see {@link range}) and
* get (see {@link get}) methods will throw an exception.
*
* If the field is a {@link ChronoField} then the query is implemented here.
* The supported fields (see {@link isSupported}) will return valid
* values based on this date-time.
* The supported fields are:
*
* * {@link MONTH_OF_YEAR}
* * {@link YEAR}
*
* All other {@link ChronoField} instances will return false.
*
* If the field is not a {@link ChronoField}, then the result of this method
* is obtained by invoking {@link TemporalField.isSupportedBy}
* passing `this` as the argument.
* Whether the field is supported is determined by the field.
*
* @param {TemporalField} field the field to check, null returns false
* @return {boolean} true if the field is supported on this month-day, false if not
*/
isSupported(field) {
if (field instanceof ChronoField) {
return field === ChronoField.MONTH_OF_YEAR || field === ChronoField.DAY_OF_MONTH;
}
return field != null && field.isSupportedBy(this);
}
/**
* Gets the range of valid values for the specified field.
*
* The range object expresses the minimum and maximum valid values for a field.
* This month-day is used to enhance the accuracy of the returned range.
* If it is not possible to return the range, because the field is not supported
* or for some other reason, an exception is thrown.
*
* If the field is a {@link ChronoField} then the query is implemented here.
* The supported fields (see {@link isSupported}) will return
* appropriate range instances.
* All other {@link ChronoField} instances will throw a {@link DateTimeException}.
*
* If the field is not a {@link ChronoField}, then the result of this method
* is obtained by invoking {@link TemporalField.rangeRefinedBy}
* passing `this` as the argument.
* Whether the range can be obtained is determined by the field.
*
* @param {TemporalField} field the field to query the range for, not null
* @return {ValueRange} the range of valid values for the field, not null
* @throws DateTimeException if the range for the field cannot be obtained
*/
range(field) {
if (field === ChronoField.MONTH_OF_YEAR) {
return field.range();
} else if (field === ChronoField.DAY_OF_MONTH) {
return ValueRange.of(1, this.month().minLength(), this.month().maxLength());
}
return super.range(field);
}
/**
* Gets the value of the specified field from this month-day as an `int`.
*
* This queries this month-day for the value for the specified field.
* The returned value will always be within the valid range of values for the field.
* If it is not possible to return the value, because the field is not supported
* or for some other reason, an exception is thrown.
*
* If the field is a {@link ChronoField} then the query is implemented here.
* The supported fields (see {@link isSupported}) will return valid
* values based on this month-day.
* All other {@link ChronoField} instances will throw a {@link DateTimeException}.
*
* If the field is not a {@link ChronoField}, then the result of this method
* is obtained by invoking {@link TemporalField.getFrom}
* passing `this` as the argument. Whether the value can be obtained,
* and what the value represents, is determined by the field.
*
* @param {TemporalField} field the field to get, not null
* @return {number} the value for the field
* @throws DateTimeException if a value for the field cannot be obtained
* @throws ArithmeticException if numeric overflow occurs
*/
get(field) {
return this.range(field).checkValidIntValue(this.getLong(field), field);
}
/**
* Gets the value of the specified field from this month-day as a `long`.
*
* This queries this month-day for the value for the specified field.
* If it is not possible to return the value, because the field is not supported
* or for some other reason, an exception is thrown.
*
* If the field is a {@link ChronoField} then the query is implemented here.
* The supported fields (see {@link isSupported}) will return valid
* values based on this month-day.
* All other {@link ChronoField} instances will throw a {@link DateTimeException}.
*
* If the field is not a {@link ChronoField}, then the result of this method
* is obtained by invoking {@link TemporalField.getFrom}
* passing `this` as the argument. Whether the value can be obtained,
* and what the value represents, is determined by the field.
*
* @param {TemporalField} field the field to get, not null
* @return {number} the value for the field
* @throws DateTimeException if a value for the field cannot be obtained
* @throws ArithmeticException if numeric overflow occurs
*/
getLong(field) {
requireNonNull(field, 'field');
if (field instanceof ChronoField) {
switch (field) {
// alignedDOW and alignedWOM not supported because they cannot be set in with()
case ChronoField.DAY_OF_MONTH: return this._day;
case ChronoField.MONTH_OF_YEAR: return this._month;
}
throw new UnsupportedTemporalTypeException(`Unsupported field: ${field}`);
}
return field.getFrom(this);
}
//-----------------------------------------------------------------------
/**
* Checks if the year is valid for this month-day.
*
* This method checks whether this month and day and the input year form
* a valid date. This can only return false for February 29th.
*
* @param {number} year the year to validate, an out of range value returns false
* @return {boolean} true if the year is valid for this month-day
* @see Year#isValidMonthDay(MonthDay)
*/
isValidYear(year) {
return (this._day === 29 && this._month === 2 && Year.isLeap(year) === false) === false;
}
//-----------------------------------------------------------------------
/**
* Returns a copy of this {@link MonthDay} with the month-of-year altered.
*
* This returns a month-day with the specified month.
* If the day-of-month is invalid for the specified month, the day will
* be adjusted to the last valid day-of-month.
*
* This instance is immutable and unaffected by this method call.
*
* @param {number} month the month-of-year to set in the returned month-day, from 1 (January) to 12 (December)
* @return {MonthDay} based on this month-day with the requested month, not null
* @throws DateTimeException if the month-of-year value is invalid
*/
withMonth(month) {
return this.with(Month.of(month));
}
/**
* Returns a copy of this {@link MonthDay} with the month-of-year altered.
*
* This returns a month-day with the specified month.
* If the day-of-month is invalid for the specified month, the day will
* be adjusted to the last valid day-of-month.
*
* This instance is immutable and unaffected by this method call.
*
* @param {Month} month the month-of-year to set in the returned month-day, not null
* @return {MonthDay} based on this month-day with the requested month, not null
*/
with(month) {
requireNonNull(month, 'month');
if (month.value() === this._month) {
return this;
}
const day = Math.min(this._day, month.maxLength());
return new MonthDay(month.value(), day);
}
/**
* Returns a copy of this {@link MonthDay} with the day-of-month altered.
*
* This returns a month-day with the specified day-of-month.
* If the day-of-month is invalid for the month, an exception is thrown.
*
* This instance is immutable and unaffected by this method call.
*
* @param {number} dayOfMonth the day-of-month to set in the return month-day, from 1 to 31
* @return {MonthDay} based on this month-day with the requested day, not null
* @throws DateTimeException if the day-of-month value is invalid
* @throws DateTimeException if the day-of-month is invalid for the month
*/
withDayOfMonth(dayOfMonth) {
if (dayOfMonth === this._day) {
return this;
}
return MonthDay.of(this._month, dayOfMonth);
}
//-----------------------------------------------------------------------
/**
* Queries this month-day using the specified query.
*
* This queries this month-day using the specified query strategy object.
* The {@link TemporalQuery} object defines the logic to be used to
* obtain the result. Read the documentation of the query to understand
* what the result of this method will be.
*
* The result of this method is obtained by invoking the
* {@link TemporalQuery#queryFrom} method on the
* specified query passing `this` as the argument.
*
* @param {TemporalQuery} query the query to invoke, not null
* @return {*} the query result, null may be returned (defined by the query)
* @throws DateTimeException if unable to query (defined by the query)
* @throws ArithmeticException if numeric overflow occurs (defined by the query)
*/
query(query) {
requireNonNull(query, 'query');
requireInstance(query, TemporalQuery, 'query');
if (query === TemporalQueries.chronology()) {
return IsoChronology.INSTANCE;
}
return super.query(query);
}
/**
* Adjusts the specified temporal object to have this month-day.
*
* This returns a temporal object of the same observable type as the input
* with the month and day-of-month changed to be the same as this.
*
* The adjustment is equivalent to using {@link Temporal#with}
* twice, passing {@link ChronoField#MONTH_OF_YEAR} and
* {@link ChronoField#DAY_OF_MONTH} as the fields.
* If the specified temporal object does not use the ISO calendar system then
* a {@link DateTimeException} is thrown.
*
* In most cases, it is clearer to reverse the calling pattern by using
* {@link Temporal#with}:
* <pre>
* // these two lines are equivalent, but the second approach is recommended
* temporal = thisMonthDay.adjustInto(temporal);
* temporal = temporal.with(thisMonthDay);
* </pre>
*
* This instance is immutable and unaffected by this method call.
*
* @param {Temporal} temporal the target object to be adjusted, not null
* @return {Temporal} the adjusted object, not null
* @throws DateTimeException if unable to make the adjustment
* @throws ArithmeticException if numeric overflow occurs
*/
adjustInto(temporal) {
requireNonNull(temporal, 'temporal');
/* TODO: only IsoChronology for now
if (Chronology.from(temporal).equals(IsoChronology.INSTANCE) == false) {
throw new DateTimeException("Adjustment only supported on ISO date-time");
}*/
temporal = temporal.with(ChronoField.MONTH_OF_YEAR, this._month);
return temporal.with(ChronoField.DAY_OF_MONTH, Math.min(temporal.range(ChronoField.DAY_OF_MONTH).maximum(), this._day));
}
//-----------------------------------------------------------------------
/**
* Combines this month-day with a year to create a {@link LocalDate}.
*
* This returns a {@link LocalDate} formed from this month-day and the specified year.
*
* A month-day of February 29th will be adjusted to February 28th in the resulting
* date if the year is not a leap year.
*
* This instance is immutable and unaffected by this method call.
*
* @param {number} year the year to use, from MIN_YEAR to MAX_YEAR
* @return {LocalDate} the local date formed from this month-day and the specified year, not null
* @throws DateTimeException if the year is outside the valid range of years
*/
atYear(year) {
return LocalDate.of(year, this._month, this.isValidYear(year) ? this._day : 28);
}
//-----------------------------------------------------------------------
/**
* Compares this month-day to another month-day.
*
* The comparison is based first on value of the month, then on the value of the day.
* It is "consistent with equals", as defined by {@link Comparable}.
*
* @param {MonthDay} other the other month-day to compare to, not null
* @return {number} the comparator value, negative if less, positive if greater
*/
compareTo(other) {
requireNonNull(other, 'other');
requireInstance(other, MonthDay, 'other');
let cmp = (this._month - other.monthValue());
if (cmp === 0) {
cmp = (this._day - other.dayOfMonth());
}
return cmp;
}
/**
* Is this month-day after the specified month-day.
*
* @param {MonthDay} other the other month-day to compare to, not null
* @return {boolean} true if this is after the specified month-day
*/
isAfter(other) {
requireNonNull(other, 'other');
requireInstance(other, MonthDay, 'other');
return this.compareTo(other) > 0;
}
/**
* Is this month-day before the specified month-day.
*
* @param {MonthDay} other the other month-day to compare to, not null
* @return {boolean} true if this point is before the specified month-day
*/
isBefore(other) {
requireNonNull(other, 'other');
requireInstance(other, MonthDay, 'other');
return this.compareTo(other) < 0;
}
//-----------------------------------------------------------------------
/**
* Checks if this month-day is equal to another month-day.
*
* The comparison is based on the time-line position of the month-day within a year.
*
* @param {*} obj the object to check, null returns false
* @return {boolean} true if this is equal to the other month-day
*/
equals(obj) {
if (this === obj) {
return true;
}
if (obj instanceof MonthDay) {
const other = obj;
return this.monthValue() === other.monthValue() && this.dayOfMonth() === other.dayOfMonth();
}
return false;
}
//-----------------------------------------------------------------------
/**
* Outputs this month-day as a string, such as `--12-03`.
*
* The output will be in the format `--MM-dd`:
*
* @return {String} a string representation of this month-day, not null
*/
toString() {
return `--${
this._month < 10 ? '0' : ''}${this._month
}${this._day < 10 ? '-0' : '-'}${this._day}`;
}
/**
* toJSON() use by JSON.stringify
* delegates to toString()
*
* @return {string}
*/
toJSON() {
return this.toString();
}
/**
* Outputs this month-day as a string using the formatter.
*
* This month-day will be passed to the formatter
* print method (see {@link DateTimeFormatter#format}).
*
* @param {DateTimeFormatter} formatter the formatter to use, not null
* @return {String} the formatted month-day string, not null
* @throws DateTimeException if an error occurs during printing
*/
format(formatter) {
requireNonNull(formatter, 'formatter');
requireInstance(formatter, DateTimeFormatter, 'formatter');
return formatter.format(this);
}
}
let PARSER;
export function _init() {
PARSER = new DateTimeFormatterBuilder()
.appendLiteral('--')
.appendValue(ChronoField.MONTH_OF_YEAR, 2)
.appendLiteral('-')
.appendValue(ChronoField.DAY_OF_MONTH, 2)
.toFormatter();
MonthDay.FROM = createTemporalQuery('MonthDay.FROM', (temporal) => {
return MonthDay.from(temporal);
});
}

757
node_modules/@js-joda/core/src/OffsetDateTime.js generated vendored Normal file
View File

@@ -0,0 +1,757 @@
/**
* @copyright (c) 2016-present, Philipp Thürwächter & Pattrick Hüper & js-joda contributors
* @copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
import { ChronoField } from './temporal/ChronoField';
import { ChronoUnit } from './temporal/ChronoUnit';
import { Temporal } from './temporal/Temporal';
import { Clock } from './Clock';
import { DateTimeFormatter } from './format/DateTimeFormatter';
import { Instant } from './Instant';
import { IsoChronology } from './chrono/IsoChronology';
import { LocalDateTime } from './LocalDateTime';
import { LocalDate } from './LocalDate';
import { LocalTime } from './LocalTime';
import { MathUtil } from './MathUtil';
import { OffsetTime } from './OffsetTime';
import { TemporalQueries } from './temporal/TemporalQueries';
import { ZonedDateTime } from './ZonedDateTime';
import { ZoneId } from './ZoneId';
import { ZoneOffset } from './ZoneOffset';
import { DateTimeException, IllegalArgumentException } from './errors';
import { createTemporalQuery } from './temporal/TemporalQuery';
import { requireInstance, requireNonNull } from './assert';
/**
* A date-time with an offset from UTC/Greenwich in the ISO-8601 calendar system,
* such as 2007-12-23T10:15:30+01:00.
*/
export class OffsetDateTime extends Temporal {
/**
* @param {TemporaroAccessor} temporal
* @return {OffsetDateTime}
*/
static from(temporal) {
requireNonNull(temporal, 'temporal');
if (temporal instanceof OffsetDateTime) {
return temporal;
}
try {
const offset = ZoneOffset.from(temporal);
try {
const ldt = LocalDateTime.from(temporal);
return OffsetDateTime.of(ldt, offset);
} catch (_) {
const instant = Instant.from(temporal);
return OffsetDateTime.ofInstant(instant, offset);
}
} catch (ex) {
throw new DateTimeException(`Unable to obtain OffsetDateTime TemporalAccessor: ${temporal}, type ${temporal.constructor != null ? temporal.constructor.name : ''}`);
}
}
/**
* @param {Clock|ZoneId|null} clockOrZone
* @return {OffsetDateTime}
*/
static now(clockOrZone) {
if (arguments.length === 0) {
return OffsetDateTime.now(Clock.systemDefaultZone());
} else {
requireNonNull(clockOrZone, 'clockOrZone');
if (clockOrZone instanceof ZoneId) {
return OffsetDateTime.now(Clock.system(clockOrZone));
} else if (clockOrZone instanceof Clock) {
const now = clockOrZone.instant(); // called once
return OffsetDateTime.ofInstant(now, clockOrZone.zone().rules().offset(now));
} else {
throw new IllegalArgumentException('clockOrZone must be an instance of ZoneId or Clock');
}
}
}
/**
* @return {OffsetDateTime}
*/
static of() {
if (arguments.length <= 2) {
return OffsetDateTime.ofDateTime.apply(this, arguments);
} else if (arguments.length === 3) {
return OffsetDateTime.ofDateAndTime.apply(this, arguments);
} else {
return OffsetDateTime.ofNumbers.apply(this, arguments);
}
}
static ofDateTime(dateTime, offset) {
return new OffsetDateTime(dateTime, offset);
}
static ofDateAndTime(date, time, offset) {
const dt = LocalDateTime.of(date, time);
return new OffsetDateTime(dt, offset);
}
static ofNumbers(year, month, dayOfMonth, hour=0, minute=0, second=0, nanoOfSecond=0, offset) {
const dt = LocalDateTime.of(year, month, dayOfMonth, hour, minute, second, nanoOfSecond);
return new OffsetDateTime(dt, offset);
}
/**
* @param {Instant} instant
* @param {ZoneId} zone
* @return {OffsetDateTime}
*/
static ofInstant(instant, zone){
requireNonNull(instant, 'instant');
requireNonNull(zone, 'zone');
const rules = zone.rules();
const offset = rules.offset(instant);
const ldt = LocalDateTime.ofEpochSecond(instant.epochSecond(), instant.nano(), offset);
return new OffsetDateTime(ldt, offset);
}
/**
* @param {string} text
* @param {DateTimeFormatter|undefined} formatter
* @return {OffsetTime}
*/
static parse(text, formatter = DateTimeFormatter.ISO_OFFSET_DATE_TIME){
requireNonNull(formatter, 'formatter');
return formatter.parse(text, OffsetDateTime.FROM);
}
// TODO: Need java.util.Comparater interface.
// static timeLineOrder() {
//
// }
//-----------------------------------------------------------------------
/**
* @param {LocalDateTime} dateTime
* @param {ZoneOffset} offset
* @private
*/
constructor(dateTime, offset) {
super();
requireNonNull(dateTime, 'dateTime');
requireInstance(dateTime, LocalDateTime, 'dateTime');
requireNonNull(offset, 'offset');
requireInstance(offset, ZoneOffset, 'offset');
this._dateTime = dateTime;
this._offset = offset;
}
/**
*
* @param {Temporal} temporal
* @return {Temporal}
*/
adjustInto(temporal) {
return temporal
.with(ChronoField.EPOCH_DAY, this.toLocalDate().toEpochDay())
.with(ChronoField.NANO_OF_DAY, this.toLocalTime().toNanoOfDay())
.with(ChronoField.OFFSET_SECONDS, this.offset().totalSeconds());
}
until(endExclusive, unit) {
let end = OffsetDateTime.from(endExclusive);
if (unit instanceof ChronoUnit) {
end = end.withOffsetSameInstant(this._offset);
return this._dateTime.until(end._dateTime, unit);
}
return unit.between(this, end);
}
/**
* @param {ZoneId} zone
* @return {ZonedDateTime}
*/
atZoneSameInstant(zone) {
return ZonedDateTime.ofInstant(this._dateTime, this._offset, zone);
}
/**
* @param {ZoneId} zone
* @return {ZonedDateTime}
*/
atZoneSimilarLocal(zone) {
return ZonedDateTime.ofLocal(this._dateTime, zone, this._offset);
}
query(query) {
requireNonNull(query, 'query');
if (query === TemporalQueries.chronology()) {
return IsoChronology.INSTANCE;
} else if (query === TemporalQueries.precision()) {
return ChronoUnit.NANOS;
} else if (query === TemporalQueries.offset() || query === TemporalQueries.zone()) {
return this.offset();
} else if (query === TemporalQueries.localDate()) {
return this.toLocalDate();
} else if (query === TemporalQueries.localTime()) {
return this.toLocalTime();
} else if (query === TemporalQueries.zoneId()) {
return null;
}
return super.query(query);
}
get(field) {
if (field instanceof ChronoField) {
switch (field) {
case ChronoField.INSTANT_SECONDS: throw new DateTimeException(`Field too large for an int: ${field}`);
case ChronoField.OFFSET_SECONDS: return this.offset().totalSeconds();
}
return this._dateTime.get(field);
}
return super.get(field);
}
getLong(field) {
if (field instanceof ChronoField) {
switch (field) {
case ChronoField.INSTANT_SECONDS: return this.toEpochSecond();
case ChronoField.OFFSET_SECONDS: return this.offset().totalSeconds();
}
return this._dateTime.getLong(field);
}
return field.getFrom(this);
}
/**
* @return {ZoneOffset}
*/
offset() {
return this._offset;
}
/**
* @return {number} the year, from MIN_YEAR to MAX_YEAR
*/
year() {
return this._dateTime.year();
}
/**
* @return {number} the month-of-year, from 1 to 12
* @see #month()
*/
monthValue() {
return this._dateTime.monthValue();
}
/**
* @return {{number} }the month-of-year, not null
* @see #monthValue()
*/
month() {
return this._dateTime.month();
}
/**
* @return {number} the day-of-month, from 1 to 31
*/
dayOfMonth() {
return this._dateTime.dayOfMonth();
}
/**
* @return {number} the day-of-year, from 1 to 365, or 366 in a leap year
*/
dayOfYear() {
return this._dateTime.dayOfYear();
}
/**
* @return {number} the day-of-week, not null
*/
dayOfWeek() {
return this._dateTime.dayOfWeek();
}
/**
* @return {number} the hour-of-day, from 0 to 23
*/
hour() {
return this._dateTime.hour();
}
/**
* @return {number} the minute-of-hour, from 0 to 59
*/
minute() {
return this._dateTime.minute();
}
/**
* @return {number} the second-of-minute, from 0 to 59
*/
second() {
return this._dateTime.second();
}
/**
* @return {number} the nano-of-second, from 0 to 999,999,999
*/
nano() {
return this._dateTime.nano();
}
//-----------------------------------------------------------------------
/**
* @return {LocalDateTime}the local date-time part of this date-time, not null
*/
toLocalDateTime() {
return this._dateTime;
}
/**
* @return {LocalDate} the date part of this date-time, not null
*/
toLocalDate() {
return this._dateTime.toLocalDate();
}
/**
* @return {LocalTime} the time part of this date-time, not null
*/
toLocalTime() {
return this._dateTime.toLocalTime();
}
/**
* @return {OffsetTime} an OffsetTime representing the time and offset, not null
*/
toOffsetTime() {
return OffsetTime.of(this._dateTime.toLocalTime(), this._offset);
}
/**
* @return {ZonedDateTime}a zoned date-time representing the same local date-time and offset, not null
*/
toZonedDateTime() {
return ZonedDateTime.of(this._dateTime, this._offset);
}
/**
* @return {Instant} an {@code Instant} representing the same instant, not null
*/
toInstant() {
return this._dateTime.toInstant(this._offset);
}
/**
* @return {number} the number of seconds from the epoch of 1970-01-01T00:00:00Z
*/
toEpochSecond() {
return this._dateTime.toEpochSecond(this._offset);
}
isSupported(fieldOrUnit) {
if (fieldOrUnit instanceof ChronoField) {
return fieldOrUnit.isDateBased() || fieldOrUnit.isTimeBased();
}
if (fieldOrUnit instanceof ChronoUnit) {
return fieldOrUnit.isDateBased() || fieldOrUnit.isTimeBased();
}
return fieldOrUnit != null && fieldOrUnit.isSupportedBy(this);
}
range(field) {
if (field instanceof ChronoField) {
if (field === ChronoField.INSTANT_SECONDS || field === ChronoField.OFFSET_SECONDS) {
return field.range();
}
return this._dateTime.range(field);
}
return field.rangeRefinedBy(this);
}
_withAdjuster(adjuster) {
requireNonNull(adjuster);
// optimizations
if (adjuster instanceof LocalDate || adjuster instanceof LocalTime || adjuster instanceof LocalDateTime) {
return this._withDateTimeOffset(this._dateTime.with(adjuster), this._offset);
} else if (adjuster instanceof Instant) {
return OffsetDateTime.ofInstant(adjuster, this._offset);
} else if (adjuster instanceof ZoneOffset) {
return this._withDateTimeOffset(this._dateTime, adjuster);
} else if (adjuster instanceof OffsetDateTime) {
return adjuster;
}
return adjuster.adjustInto(this);
}
_withField(field, newValue) {
requireNonNull(field);
if (field instanceof ChronoField) {
const f = field;
switch (f) {
case ChronoField.INSTANT_SECONDS: return OffsetDateTime.ofInstant(Instant.ofEpochSecond(newValue, this.nano()), this._offset);
case ChronoField.OFFSET_SECONDS: {
return this._withDateTimeOffset(this._dateTime, ZoneOffset.ofTotalSeconds(f.checkValidIntValue(newValue)));
}
}
return this._withDateTimeOffset(this._dateTime.with(field, newValue), this._offset);
}
return field.adjustInto(this, newValue);
}
_withDateTimeOffset(dateTime, offset) {
if (this._dateTime === dateTime && this._offset.equals(offset)) {
return this;
}
return new OffsetDateTime(dateTime, offset);
}
/**
* @param {int} year
* @return {OffsetDateTime}
*/
withYear(year) {
return this._withDateTimeOffset(this._dateTime.withYear(year), this._offset);
}
/**
* @param {int} month
* @return {OffsetDateTime}
*/
withMonth(month) {
return this._withDateTimeOffset(this._dateTime.withMonth(month), this._offset);
}
/**
* @param {int} dayOfMonth
* @return {OffsetDateTime}
*/
withDayOfMonth(dayOfMonth) {
return this._withDateTimeOffset(this._dateTime.withDayOfMonth(dayOfMonth), this._offset);
}
/**
* @param {int} dayOfYear
* @return {OffsetDateTime}
*/
withDayOfYear(dayOfYear) {
return this._withDateTimeOffset(this._dateTime.withDayOfYear(dayOfYear), this._offset);
}
/**
* @param {int} hour
* @return {OffsetDateTime}
*/
withHour(hour) {
return this._withDateTimeOffset(this._dateTime.withHour(hour), this._offset);
}
/**
* @param {int} minute
* @return {OffsetDateTime}
*/
withMinute(minute) {
return this._withDateTimeOffset(this._dateTime.withMinute(minute), this._offset);
}
/**
* @param {int} second
* @return {OffsetDateTime}
*/
withSecond(second) {
return this._withDateTimeOffset(this._dateTime.withSecond(second), this._offset);
}
/**
* @param {int} nanoOfSecond
* @return {OffsetDateTime}
*/
withNano(nanoOfSecond) {
return this._withDateTimeOffset(this._dateTime.withNano(nanoOfSecond), this._offset);
}
/**
* @param {ZoneOffset} offset
* @return {OffsetDateTime}
*/
withOffsetSameLocal(offset) {
requireNonNull(offset, 'offset');
return this._withDateTimeOffset(this._dateTime, offset);
}
/**
* @param {ZoneOffset} offset
* @return {OffsetDateTime}
*/
withOffsetSameInstant(offset) {
requireNonNull(offset, 'offset');
if (offset.equals(this._offset)) {
return this;
}
const difference = offset.totalSeconds() - this._offset.totalSeconds();
const adjusted = this._dateTime.plusSeconds(difference);
return new OffsetDateTime(adjusted, offset);
}
/**
* @param {TemporalUnit} unit
* @return {OffsetDateTime}
*/
truncatedTo(unit) {
return this._withDateTimeOffset(this._dateTime.truncatedTo(unit), this._offset);
}
_plusAmount(amount) {
requireNonNull(amount, 'amount');
return amount.addTo(this);
}
_plusUnit(amountToAdd, unit) {
if (unit instanceof ChronoUnit) {
return this._withDateTimeOffset(this._dateTime.plus(amountToAdd, unit), this._offset);
}
return unit.addTo(this, amountToAdd);
}
/**
* @param {int} years
* @return {OffsetTime}
*/
plusYears(years) {
return this._withDateTimeOffset(this._dateTime.plusYears(years), this._offset);
}
/**
* @param {int} months
* @return {OffsetTime}
*/
plusMonths(months) {
return this._withDateTimeOffset(this._dateTime.plusMonths(months), this._offset);
}
/**
* @param {int} weeks
* @return {OffsetTime}
*/
plusWeeks(weeks) {
return this._withDateTimeOffset(this._dateTime.plusWeeks(weeks), this._offset);
}
/**
* @param {int} days
* @return {OffsetTime}
*/
plusDays(days) {
return this._withDateTimeOffset(this._dateTime.plusDays(days), this._offset);
}
/**
* @param {int} hours
* @return {OffsetTime}
*/
plusHours(hours) {
return this._withDateTimeOffset(this._dateTime.plusHours(hours), this._offset);
}
/**
* @param {int} minutes
* @return {OffsetTime}
*/
plusMinutes(minutes) {
return this._withDateTimeOffset(this._dateTime.plusMinutes(minutes), this._offset);
}
/**
* @param {int} seconds
* @return {OffsetTime}
*/
plusSeconds(seconds) {
return this._withDateTimeOffset(this._dateTime.plusSeconds(seconds), this._offset);
}
/**
* @param {int} nanos
* @return {OffsetTime}
*/
plusNanos(nanos) {
return this._withDateTimeOffset(this._dateTime.plusNanos(nanos), this._offset);
}
_minusAmount(amount) {
requireNonNull(amount);
return amount.subtractFrom(this);
}
_minusUnit(amountToSubtract, unit) {
return this.plus(-1 * amountToSubtract, unit);
}
/**
* @param {int} years
* @return {OffsetTime}
*/
minusYears(years) {
return this._withDateTimeOffset(this._dateTime.minusYears(years), this._offset);
}
/**
* @param {int} months
* @return {OffsetTime}
*/
minusMonths(months) {
return this._withDateTimeOffset(this._dateTime.minusMonths(months), this._offset);
}
/**
* @param {int} weeks
* @return {OffsetTime}
*/
minusWeeks(weeks) {
return this._withDateTimeOffset(this._dateTime.minusWeeks(weeks), this._offset);
}
/**
* @param {int} days
* @return {OffsetTime}
*/
minusDays(days) {
return this._withDateTimeOffset(this._dateTime.minusDays(days), this._offset);
}
/**
* @param {int} hours
* @return {OffsetTime}
*/
minusHours(hours) {
return this._withDateTimeOffset(this._dateTime.minusHours(hours), this._offset);
}
/**
* @param {int} minutes
* @return {OffsetTime}
*/
minusMinutes(minutes) {
return this._withDateTimeOffset(this._dateTime.minusMinutes(minutes), this._offset);
}
/**
* @param {int} seconds
* @return {OffsetTime}
*/
minusSeconds(seconds) {
return this._withDateTimeOffset(this._dateTime.minusSeconds(seconds), this._offset);
}
/**
* @param {int} nanos
* @return {OffsetTime}
*/
minusNanos(nanos) {
return this._withDateTimeOffset(this._dateTime.minusNanos(nanos), this._offset);
}
compareTo(other) {
requireNonNull(other, 'other');
requireInstance(other, OffsetDateTime, 'other');
if (this.offset().equals(other.offset())) {
return this.toLocalDateTime().compareTo(other.toLocalDateTime());
}
let cmp = MathUtil.compareNumbers(this.toEpochSecond(), other.toEpochSecond());
if (cmp === 0) {
cmp = this.toLocalTime().nano() - other.toLocalTime().nano();
if (cmp === 0) {
cmp = this.toLocalDateTime().compareTo(other.toLocalDateTime());
}
}
return cmp;
}
/**
* @param {OffsetDateTime} other
* @return {boolean}
*/
isAfter(other) {
requireNonNull(other, 'other');
const thisEpochSec = this.toEpochSecond();
const otherEpochSec = other.toEpochSecond();
return thisEpochSec > otherEpochSec || (thisEpochSec === otherEpochSec && this.toLocalTime().nano() > other.toLocalTime().nano());
}
/**
* @param {OffsetDateTime} other
* @return {boolean}
*/
isBefore(other) {
requireNonNull(other, 'other');
const thisEpochSec = this.toEpochSecond();
const otherEpochSec = other.toEpochSecond();
return thisEpochSec < otherEpochSec || (thisEpochSec === otherEpochSec && this.toLocalTime().nano() < other.toLocalTime().nano());
}
/**
* @param {OffsetDateTime} other
* @return {boolean}
*/
isEqual(other) {
requireNonNull(other, 'other');
return this.toEpochSecond() === other.toEpochSecond() && this.toLocalTime().nano() === other.toLocalTime().nano();
}
//-----------------------------------------------------------------------
/**
* @param other
* @return {boolean}
*/
equals(other) {
if (this === other) {
return true;
}
if (other instanceof OffsetDateTime) {
return this._dateTime.equals(other._dateTime) && this._offset.equals(other._offset);
}
return false;
}
/**
* @return {number}
*/
hashCode() {
return this._dateTime.hashCode() ^ this._offset.hashCode();
}
toString() {
return this._dateTime.toString() + this._offset.toString();
}
/**
*
* @return {string} same as {@link LocalDateTime.toString}
*/
toJSON() {
return this.toString();
}
/**
* @param {DateTimeFormatter} formatter
* @return {string}
*/
format(formatter) {
requireNonNull(formatter, 'formatter');
return formatter.format(this);
}
}
export function _init() {
OffsetDateTime.MIN = LocalDateTime.MIN.atOffset(ZoneOffset.MAX);
OffsetDateTime.MAX = LocalDateTime.MAX.atOffset(ZoneOffset.MIN);
OffsetDateTime.FROM = createTemporalQuery('OffsetDateTime.FROM', (temporal) => {
return OffsetDateTime.from(temporal);
});
}

621
node_modules/@js-joda/core/src/OffsetTime.js generated vendored Normal file
View File

@@ -0,0 +1,621 @@
/**
* @copyright (c) 2016-present, Philipp Thürwächter & Pattrick Hüper & js-joda contributors
* @copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
import { ChronoField } from './temporal/ChronoField';
import { ChronoUnit } from './temporal/ChronoUnit';
import { Temporal } from './temporal/Temporal';
import { Clock } from './Clock';
import { DateTimeException, UnsupportedTemporalTypeException } from './errors';
import { DateTimeFormatter } from './format/DateTimeFormatter';
import { Instant, LocalTime } from './js-joda';
import { MathUtil } from './MathUtil';
import { OffsetDateTime } from './OffsetDateTime';
import { TemporalQueries } from './temporal/TemporalQueries';
import { ZoneId } from './ZoneId';
import { ZoneOffset } from './ZoneOffset';
import { createTemporalQuery } from './temporal/TemporalQuery';
import { requireInstance, requireNonNull } from './assert';
/**
* A time with an offset from UTC/Greenwich in the ISO-8601 calendar system, such as 10:15:30+01:00.
*/
export class OffsetTime extends Temporal {
/**
* @param {!TemporalAccessor} temporal
* @return {OffsetTime}
*/
static from(temporal) {
requireNonNull(temporal, 'temporal');
if (temporal instanceof OffsetTime) {
return temporal;
} else if (temporal instanceof OffsetDateTime) {
return temporal.toOffsetTime();
}
try {
const time = LocalTime.from(temporal);
const offset = ZoneOffset.from(temporal);
return new OffsetTime(time, offset);
} catch(ex) {
throw new DateTimeException(`Unable to obtain OffsetTime TemporalAccessor: ${temporal}, type ${temporal.constructor != null ? temporal.constructor.name : ''}`);
}
}
/**
* @param {Clock|ZoneId} clockOrZone
* @return {OffsetTime}
*/
static now(clockOrZone) {
if (arguments.length === 0){
return OffsetTime._now(Clock.systemDefaultZone());
} else if (clockOrZone instanceof Clock){
return OffsetTime._now(clockOrZone);
} else {
return OffsetTime._now(Clock.system(clockOrZone));
}
}
/**
* @param {Clock} clock - the clock to use, defaults to Clock.systemDefaultZone()
* @return {OffsetTime} the current offset date-time, not null
*/
static _now(clock) {
requireNonNull(clock, 'clock');
const now = clock.instant();
return OffsetTime.ofInstant(now, clock.zone().rules().offset(now));
}
/**
* @return {OffsetTime}
*/
static of(){
if (arguments.length <= 2) {
return OffsetTime.ofTimeAndOffset.apply(this, arguments);
} else {
return OffsetTime.ofNumbers.apply(this, arguments);
}
}
/**
* @param {int} hour
* @param {int} minute
* @param {int} second
* @param {int} nanoOfSecond
* @param {ZoneOffset} offset
* @return {OffsetTime}
*/
static ofNumbers(hour, minute, second, nanoOfSecond, offset) {
const time = LocalTime.of(hour, minute, second, nanoOfSecond);
return new OffsetTime(time, offset);
}
/**
* @param {LocalTime} time
* @param {ZoneOffset} offset
* @return {OffsetTime}
*/
static ofTimeAndOffset(time, offset) {
return new OffsetTime(time, offset);
}
/**
* @param {!Instant} instant
* @param {!ZoneId} zone
* @return {!OffsetTime}
*/
static ofInstant( instant, zone){
requireNonNull(instant, 'instant');
requireInstance(instant, Instant, 'instant');
requireNonNull(zone, 'zone');
requireInstance(zone, ZoneId, 'zone');
const rules = zone.rules();
const offset = rules.offset(instant);
let secsOfDay = instant.epochSecond() % LocalTime.SECONDS_PER_DAY;
secsOfDay = (secsOfDay + offset.totalSeconds()) % LocalTime.SECONDS_PER_DAY;
if (secsOfDay < 0) {
secsOfDay += LocalTime.SECONDS_PER_DAY;
}
const time = LocalTime.ofSecondOfDay(secsOfDay, instant.nano());
return new OffsetTime(time, offset);
}
/**
* @param {string} text
* @param {DateTimeFormatter} formatter
* @return {OffsetTime}
*/
static parse(text, formatter= DateTimeFormatter.ISO_OFFSET_TIME) {
requireNonNull(formatter, 'formatter');
return formatter.parse(text, OffsetTime.FROM);
}
//-----------------------------------------------------------------------
/**
* @param {LocalTime} time
* @param {ZoneOffset} offset
* @private
*/
constructor(time, offset) {
super();
requireNonNull(time, 'time');
requireInstance(time, LocalTime, 'time');
requireNonNull(offset, 'offset');
requireInstance(offset, ZoneOffset, 'offset');
this._time = time;
this._offset = offset;
}
/**
* @param {TemporalAdjuster} temporal - the target object to be adjusted, not null
* @return {Temporal} the adjusted object, not null
* @throws {DateTimeException} if unable to make the adjustment
* @throws {ArithmeticException} if numeric overflow occurs
*/
adjustInto(temporal) {
return temporal
.with(ChronoField.NANO_OF_DAY, this._time.toNanoOfDay())
.with(ChronoField.OFFSET_SECONDS, this.offset().totalSeconds());
}
/**
* @param {LocalDate} date - the date to combine with, not null
* @return {OffsetDateTime} the offset date-time formed from this time and the specified date, not null
*/
atDate(date) {
return OffsetDateTime.of(date, this._time, this._offset);
}
/**
* @param {DateTimeFormatter} formatter - the formatter to use, not null
* @return {string} the formatted time string, not null
* @throws {DateTimeException} if an error occurs during printing
*/
format(formatter) {
requireNonNull(formatter, 'formatter');
return formatter.format(this, OffsetTime.FROM);
}
/**
* @param {TemporalField} field - the field to get, not null
* @return {number} the value for the field
* @throws {DateTimeException} if a value for the field cannot be obtained
* @throws {ArithmeticException} if numeric overflow occurs
*/
get(field) {
return super.get(field);
}
/**
* @param {TemporalField} field - the field to get, not null
* @return {number} the value for the field
* @throws {DateTimeException} if a value for the field cannot be obtained
* @trhows {UnsupportedTemporalTypeException}
* @throws {ArithmeticException} if numeric overflow occurs
*/
getLong(field) {
if (field instanceof ChronoField) {
if (field === ChronoField.OFFSET_SECONDS) {
return this._offset.totalSeconds();
}
return this._time.getLong(field);
}
return field.getFrom(this);
}
/**
* @return {int}
*/
hour() {
return this._time.hour();
}
/**
* @return {int}
*/
minute() {
return this._time.minute();
}
/**
* @return {int}
*/
second() {
return this._time.second();
}
/**
* @return {int}
*/
nano() {
return this._time.nano();
}
/**
* @return {ZoneOffset}
*/
offset() {
return this._offset;
}
/**
* @param {OffsetTime} other - the other time to compare to, not null
* @return {boolean} true if this is after the specified time
* @throws {NullPointerException} if `other` is null
*/
isAfter(other) {
requireNonNull(other, 'other');
return this._toEpochNano() > other._toEpochNano();
}
/**
* @param {OffsetTime} other - the other time to compare to, not null
* @return {boolean} true if this point is before the specified time
* @throws {NullPointerException} if `other` is null
*/
isBefore(other) {
requireNonNull(other, 'other');
return this._toEpochNano() < other._toEpochNano();
}
/**
* @param {OffsetTime} other - the other time to compare to, not null
* @return {boolean}
* @throws {NullPointerException} if `other` is null
*/
isEqual(other) {
requireNonNull(other, 'other');
return this._toEpochNano() === other._toEpochNano();
}
/**
* @param {TemporalField|TemporalUnit} fieldOrUnit - the field to check, null returns false
* @return {boolean} true if the field is supported on this time, false if not
*/
isSupported(fieldOrUnit) {
if (fieldOrUnit instanceof ChronoField) {
return fieldOrUnit.isTimeBased() || fieldOrUnit === ChronoField.OFFSET_SECONDS;
} else if (fieldOrUnit instanceof ChronoUnit) {
return fieldOrUnit.isTimeBased();
}
return fieldOrUnit != null && fieldOrUnit.isSupportedBy(this);
}
/**
* @param {number} hours
* @return {OffsetTime}
*/
minusHours(hours) {
return this._withLocalTimeOffset(this._time.minusHours(hours), this._offset);
}
/**
* @param {number} minutes
* @return {OffsetTime}
*/
minusMinutes(minutes) {
return this._withLocalTimeOffset(this._time.minusMinutes(minutes), this._offset);
}
/**
* @param {number} seconds
* @return {OffsetTime}
*/
minusSeconds(seconds) {
return this._withLocalTimeOffset(this._time.minusSeconds(seconds), this._offset);
}
/**
* @param {number} nanos
* @return {OffsetTime}
*/
minusNanos(nanos) {
return this._withLocalTimeOffset(this._time.minusNanos(nanos), this._offset);
}
_minusAmount(amount) {
requireNonNull(amount);
return amount.subtractFrom(this);
}
_minusUnit(amountToSubtract, unit) {
return this.plus(-1 * amountToSubtract, unit);
}
_plusAmount(amount) {
requireNonNull(amount);
return amount.addTo(this);
}
/**
*
* @param amountToAdd
* @param unit
* @return {Temporal}
*/
_plusUnit(amountToAdd, unit) {
if (unit instanceof ChronoUnit) {
return this._withLocalTimeOffset(this._time.plus(amountToAdd, unit), this._offset);
}
return unit.addTo(this, amountToAdd);
}
/**
* @param {int} hours
* @return {OffsetTime}
*/
plusHours(hours) {
return this._withLocalTimeOffset(this._time.plusHours(hours), this._offset);
}
/**
* @param {int} minutes
* @return {OffsetTime}
*/
plusMinutes(minutes) {
return this._withLocalTimeOffset(this._time.plusMinutes(minutes), this._offset);
}
/**
* @param {int} seconds
* @return {OffsetTime}
*/
plusSeconds(seconds) {
return this._withLocalTimeOffset(this._time.plusSeconds(seconds), this._offset);
}
/**
* @param {int} nanos
* @return {OffsetTime}
*/
plusNanos(nanos) {
return this._withLocalTimeOffset(this._time.plusNanos(nanos), this._offset);
}
/**
* @param {TemporalQuery} query - the query to invoke, not null
* @return {*} the query result, null may be returned (defined by the query)
* @throws {DateTimeException} if unable to query (defined by the query)
* @throws {ArithmeticException} if numeric overflow occurs (defined by the query)
*/
query(query) {
requireNonNull(query, 'query');
if (query === TemporalQueries.precision()) {
return ChronoUnit.NANOS;
} else if (query === TemporalQueries.offset() || query === TemporalQueries.zone()) {
return this.offset();
} else if (query === TemporalQueries.localTime()) {
return this._time;
} else if (query === TemporalQueries.chronology() || query === TemporalQueries.localDate() || query === TemporalQueries.zoneId()) {
return null;
}
return super.query(query);
}
/**
* @param {TemporalField} field - the field to query the range for, not null
* @return {ValueRange} the range of valid values for the field, not null
* @throws {DateTimeException} if the range for the field cannot be obtained
*/
range(field) {
if (field instanceof ChronoField) {
if (field === ChronoField.OFFSET_SECONDS) {
return field.range();
}
return this._time.range(field);
}
return field.rangeRefinedBy(this);
}
/**
* @return {LocalTime}
*/
toLocalTime() {
return this._time;
}
/**
* @param {TemporalUnit} unit - the unit to truncate to, not null
* @return {OffsetTime} a {@link LocalTime} based on this time with the time truncated, not null
* @throws {DateTimeException} if unable to truncate
*/
truncatedTo(unit) {
return this._withLocalTimeOffset(this._time.truncatedTo(unit), this._offset);
}
/**
* @param {Temporal} endExclusive - the end time, which is converted to a {@link LocalTime}, not null
* @param {TemporalUnit} unit - the unit to measure the period in, not null
* @return {number} the amount of the period between this time and the end time
* @throws {DateTimeException} if the period cannot be calculated
* @throws {ArithmeticException} if numeric overflow occurs
*/
until(endExclusive, unit) {
requireNonNull(endExclusive, 'endExclusive');
requireNonNull(unit, 'unit');
const end = OffsetTime.from(endExclusive);
if (unit instanceof ChronoUnit) {
const nanosUntil = end._toEpochNano() - this._toEpochNano(); // no overflow
switch (unit) {
case ChronoUnit.NANOS: return nanosUntil;
case ChronoUnit.MICROS: return MathUtil.intDiv(nanosUntil, 1000);
case ChronoUnit.MILLIS: return MathUtil.intDiv(nanosUntil, 1000000);
case ChronoUnit.SECONDS: return MathUtil.intDiv(nanosUntil, LocalTime.NANOS_PER_SECOND);
case ChronoUnit.MINUTES: return MathUtil.intDiv(nanosUntil, LocalTime.NANOS_PER_MINUTE);
case ChronoUnit.HOURS: return MathUtil.intDiv(nanosUntil, LocalTime.NANOS_PER_HOUR);
case ChronoUnit.HALF_DAYS: return MathUtil.intDiv(nanosUntil, (12 * LocalTime.NANOS_PER_HOUR));
}
throw new UnsupportedTemporalTypeException(`Unsupported unit: ${unit}`);
}
return unit.between(this, end);
}
/**
* @param {int} hour
* @return {OffsetTime}
*/
withHour(hour) {
return this._withLocalTimeOffset(this._time.withHour(hour), this._offset);
}
/**
* @param {int} minute
* @return {OffsetTime}
*/
withMinute(minute) {
return this._withLocalTimeOffset(this._time.withMinute(minute), this._offset);
}
/**
* @param {int} second
* @return {OffsetTime}
*/
withSecond(second) {
return this._withLocalTimeOffset(this._time.withSecond(second), this._offset);
}
/**
* @param {int} nano
* @return {OffsetTime}
*/
withNano(nano) {
return this._withLocalTimeOffset(this._time.withNano(nano), this._offset);
}
/**
* @param {ZoneOffset} offset
* @return {OffsetTime}
*/
withOffsetSameInstant(offset) {
requireNonNull(offset, 'offset');
if (offset.equals(this._offset)) {
return this;
}
const difference = offset.totalSeconds() - this._offset.totalSeconds();
const adjusted = this._time.plusSeconds(difference);
return new OffsetTime(adjusted, offset);
}
/**
* @param {ZoneOffset} offset
* @return {OffsetTime}
*/
withOffsetSameLocal(offset) {
return offset != null && offset.equals(this._offset) ? this : new OffsetTime(this._time, offset);
}
_toEpochNano() {
const nod = this._time.toNanoOfDay();
const offsetNanos = this._offset.totalSeconds() * LocalTime.NANOS_PER_SECOND;
return nod - offsetNanos;
}
_withAdjuster(adjuster) {
requireNonNull(adjuster, 'adjuster');
// optimizations
if (adjuster instanceof LocalTime) {
return this._withLocalTimeOffset(adjuster, this._offset);
} else if (adjuster instanceof ZoneOffset) {
return this._withLocalTimeOffset(this._time, adjuster);
} else if (adjuster instanceof OffsetTime) {
return adjuster;
}
return adjuster.adjustInto(this);
}
_withField(field, newValue) {
requireNonNull(field, 'field');
if (field instanceof ChronoField) {
if (field === ChronoField.OFFSET_SECONDS) {
return this._withLocalTimeOffset(this._time, ZoneOffset.ofTotalSeconds(field.checkValidIntValue(newValue)));
}
return this._withLocalTimeOffset(this._time.with(field, newValue), this._offset);
}
return field.adjustInto(this, newValue);
}
/**
* @private
* @param {LocalTime} time
* @param {ZoneOffset} offset
* @return {OffsetTime}
*/
_withLocalTimeOffset(time, offset) {
if (this._time === time && this._offset.equals(offset)) {
return this;
}
return new OffsetTime(time, offset);
}
//---------------------------------
/**
* @param {OffsetTime} other - the other time to compare to, not null
* @return {int} the comparator value, negative if less, positive if greater
* @throws {NullPointerException} if `other` is null
*/
compareTo(other) {
requireNonNull(other, 'other');
requireInstance(other, OffsetTime, 'other');
if (this._offset.equals(other._offset)) {
return this._time.compareTo(other._time);
}
const compare = MathUtil.compareNumbers(this._toEpochNano(), other._toEpochNano());
if (compare === 0) {
return this._time.compareTo(other._time);
}
return compare;
}
/**
* @param {*} other - the object to check, null returns false
* @return {boolean} true if this is equal to the other time
*/
equals(other) {
if (this === other) {
return true;
}
if (other instanceof OffsetTime) {
return this._time.equals(other._time) && this._offset.equals(other._offset);
}
return false;
}
/**
* @return {number}
*/
hashCode() {
return this._time.hashCode() ^ this._offset.hashCode();
}
/**
* @return {string}
*/
toString() {
return this._time.toString() + this._offset.toString();
}
/**
*
* @return {string} same as {@link LocalDateTime.toString}
*/
toJSON() {
return this.toString();
}
}
export function _init() {
OffsetTime.MIN = OffsetTime.ofNumbers(0, 0, 0,0, ZoneOffset.MAX);
OffsetTime.MAX = OffsetTime.ofNumbers(23, 59, 59,999999999, ZoneOffset.MIN);
OffsetTime.FROM = createTemporalQuery('OffsetTime.FROM', (temporal) => {
return OffsetTime.from(temporal);
});
}

933
node_modules/@js-joda/core/src/Period.js generated vendored Normal file
View File

@@ -0,0 +1,933 @@
/*
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
import { MathUtil } from './MathUtil';
import { requireNonNull, requireInstance } from './assert';
import { DateTimeException, UnsupportedTemporalTypeException, ArithmeticException, DateTimeParseException } from './errors';
import { IsoChronology } from './chrono/IsoChronology';
import { ChronoUnit } from './temporal/ChronoUnit';
import { TemporalAmount } from './temporal/TemporalAmount';
import { LocalDate } from './LocalDate';
/**
* The pattern for parsing.
*/
const PATTERN = /([-+]?)P(?:([-+]?[0-9]+)Y)?(?:([-+]?[0-9]+)M)?(?:([-+]?[0-9]+)W)?(?:([-+]?[0-9]+)D)?/;
/**
* A date-based amount of time, such as '2 years, 3 months and 4 days'.
*
* This class models a quantity or amount of time in terms of years, months and days.
* See {@link Duration} for the time-based equivalent to this class.
*
* Durations and period differ in their treatment of daylight savings time
* when added to {@link ZonedDateTime}. A {@link Duration} will add an exact
* number of seconds, thus a duration of one day is always exactly 24 hours.
* By contrast, a {@link Period} will add a conceptual day, trying to maintain
* the local time.
*
* For example, consider adding a period of one day and a duration of one day to
* 18:00 on the evening before a daylight savings gap. The {@link Period} will add
* the conceptual day and result in a {@link ZonedDateTime} at 18:00 the following day.
* By contrast, the {@link Duration} will add exactly 24 hours, resulting in a
* {@link ZonedDateTime} at 19:00 the following day (assuming a one hour DST gap).
*
* The supported units of a period are {@link ChronoUnit#YEARS},
* {@link ChronoUnit#MONTHS} and {@link ChronoUnit#DAYS}.
* All three fields are always present, but may be set to zero.
*
* The period may be used with any calendar system.
* The meaning of a 'year' or 'month' is only applied when the object is added to a date.
*
* The period is modeled as a directed amount of time, meaning that individual parts of the
* period may be negative.
*
* The months and years fields may be normalized (see {@link normalized}).
* The normalization assumes a 12 month year, so is not appropriate for all calendar systems.
*
* ### Static properties of Class {@link Period}
*
* Period.ZERO
*
* A constant for a period of zero.
*
*/
export class Period extends TemporalAmount /* extends ChronoPeriod */ {
/**
* do not call the constructor directly
* use a factory method instead
*
* @param {number} years
* @param {number} months
* @param {number} days
* @private
*/
constructor(years, months, days){
super();
const _years = MathUtil.safeToInt(years);
const _months = MathUtil.safeToInt(months);
const _days = MathUtil.safeToInt(days);
if( _years === 0 && _months === 0 && _days === 0 ){
if (!Period.ZERO) {
this._years = _years;
this._months = _months;
this._days = _days;
Period.ZERO = this;
}
return Period.ZERO;
}
/**
* The number of years.
*/
this._years = _years;
/**
* The number of months.
*/
this._months = _months;
/**
* The number of days.
*/
this._days = _days;
}
//-----------------------------------------------------------------------
/**
* Obtains a {@link Period} representing a number of years.
*
* The resulting period will have the specified years.
* The months and days units will be zero.
*
* @param {number} years - the number of years, positive or negative
* @return {Period} the period of years, not null
*/
static ofYears(years) {
return Period.create(years, 0, 0);
}
/**
* Obtains a {@link Period} representing a number of months.
*
* The resulting period will have the specified months.
* The years and days units will be zero.
*
* @param {number} months - the number of months, positive or negative
* @return {Period} the period of months, not null
*/
static ofMonths(months) {
return Period.create(0, months, 0);
}
/**
* Obtains a {@link Period} representing a number of weeks.
*
* The resulting period will have days equal to the weeks multiplied by seven.
* The years and months units will be zero.
*
* @param {number} weeks - the number of weeks, positive or negative
* @return {Period} the period of days, not null
*/
static ofWeeks(weeks) {
return Period.create(0, 0, MathUtil.safeMultiply(weeks, 7));
}
/**
* Obtains a {@link Period} representing a number of days.
*
* The resulting period will have the specified days.
* The years and months units will be zero.
*
* @param {number} days - the number of days, positive or negative
* @return {Period} the period of days, not null
*/
static ofDays(days) {
return Period.create(0, 0, days);
}
//-----------------------------------------------------------------------
/**
* Obtains a {@link Period} representing a number of years, months and days.
*
* This creates an instance based on years, months and days.
*
* @param {!number} years - the amount of years, may be negative
* @param {!number} months - the amount of months, may be negative
* @param {!number} days - the amount of days, may be negative
* @return {Period} the period of years, months and days, not null
*/
static of(years, months, days) {
return Period.create(years, months, days);
}
//-----------------------------------------------------------------------
/**
* Obtains an instance of {@link Period} from a temporal amount.
*
* This obtains a period based on the specified amount.
* A {@link TemporalAmount} represents an - amount of time, which may be
* date-based or time-based, which this factory extracts to a {@link Period}.
*
* The conversion loops around the set of units from the amount and uses
* the {@link ChronoUnit#YEARS}, {@link ChronoUnit#MONTHS}
* and {@link ChronoUnit#DAYS} units to create a period.
* If any other units are found then an exception is thrown.
*
* If the amount is a {@link ChronoPeriod} then it must use the ISO chronology.
*
* @param {TemporalAmount} amount - the temporal amount to convert, not null
* @return {Period} the equivalent period, not null
* @throws DateTimeException if unable to convert to a {@link Period}
* @throws ArithmeticException if the amount of years, months or days exceeds an int
*/
static from(amount) {
if (amount instanceof Period) {
return amount;
}
/*
if (amount instanceof ChronoPeriod) {
if (IsoChronology.INSTANCE !== amount.chronology()) {
throw new DateTimeException('Period requires ISO chronology: ' + amount);
}
}
*/
requireNonNull(amount, 'amount');
let years = 0;
let months = 0;
let days = 0;
const units = amount.units();
for (let i=0; i<units.length; i++) {
const unit = units[i];
const unitAmount = amount.get(unit);
if (unit === ChronoUnit.YEARS) {
years = MathUtil.safeToInt(unitAmount);
} else if (unit === ChronoUnit.MONTHS) {
months = MathUtil.safeToInt(unitAmount);
} else if (unit === ChronoUnit.DAYS) {
days = MathUtil.safeToInt(unitAmount);
} else {
throw new DateTimeException(`Unit must be Years, Months or Days, but was ${unit}`);
}
}
return Period.create(years, months, days);
}
//-----------------------------------------------------------------------
/**
* Obtains a {@link Period} consisting of the number of years, months,
* and days between two dates.
*
* The start date is included, but the end date is not.
* The period is calculated by removing complete months, then calculating
* the remaining number of days, adjusting to ensure that both have the same sign.
* The number of months is then split into years and months based on a 12 month year.
* A month is considered if the end day-of-month is greater than or equal to the start day-of-month.
* For example, from `2010-01-15` to `2011-03-18` is one year, two months and three days.
*
* The result of this method can be a negative period if the end is before the start.
* The negative sign will be the same in each of year, month and day.
* see {@link ChronoLocalDate.until}
*
* @param {LocalDate} startDate - the start date, inclusive, not null
* @param {LocalDate} endDate - the end date, exclusive, not null
* @return {Period} the period between this date and the end date, not null
*/
static between(startDate, endDate) {
requireNonNull(startDate, 'startDate');
requireNonNull(endDate, 'endDate');
requireInstance(startDate, LocalDate, 'startDate');
requireInstance(endDate, LocalDate, 'endDate');
return startDate.until(endDate);
}
//-----------------------------------------------------------------------
/**
* Obtains a {@link Period} from a text string such as {@link PnYnMnD}.
*
* This will parse the string produced by {@link toString} which is
* based on the ISO-8601 period formats {@link PnYnMnD} and {@link PnW}.
*
* The string starts with an optional sign, denoted by the ASCII negative
* or positive symbol. If negative, the whole period is negated.
* The ASCII letter 'P' is next in upper or lower case.
* There are then four sections, each consisting of a number and a suffix.
* At least one of the four sections must be present.
* The sections have suffixes in ASCII of 'Y', 'M', 'W' and 'D' for
* years, months, weeks and days, accepted in upper or lower case.
* The suffixes must occur in order.
* The number part of each section must consist of ASCII digits.
* The number may be prefixed by the ASCII negative or positive symbol.
* The number must parse to an `int`.
*
* The leading plus/minus sign, and negative values for other units are
* not part of the ISO-8601 standard. In addition, ISO-8601 does not
* permit mixing between the {@link PnYnMnD} and {@link PnW} formats.
* Any week-based input is multiplied by 7 and treated as a number of days.
*
* For example, the following are valid inputs:
* <pre>
* 'P2Y' -- Period.ofYears(2)
* 'P3M' -- Period.ofMonths(3)
* 'P4W' -- Period.ofWeeks(4)
* 'P5D' -- Period.ofDays(5)
* 'P1Y2M3D' -- Period.of(1, 2, 3)
* 'P1Y2M3W4D' -- Period.of(1, 2, 25)
* 'P-1Y2M' -- Period.of(-1, 2, 0)
* '-P1Y2M' -- Period.of(-1, -2, 0)
* </pre>
*
* @param {string} text - the text to parse, not null
* @return {Period} the parsed period, not null
* @throws DateTimeParseException if the text cannot be parsed to a period
*/
static parse(text) {
requireNonNull(text, 'text');
try {
return Period._parse(text);
} catch (ex){
if(ex instanceof ArithmeticException){
throw new DateTimeParseException('Text cannot be parsed to a Period', text, 0, ex);
} else {
throw ex;
}
}
}
/**
* because functions that containing a try/ catch block cant be optimized,
* we put the code in a sub function.
*/
static _parse(text){
const matches = PATTERN.exec(text);
if (matches != null) {
const negate = '-' === matches[1] ? -1 : 1;
const yearMatch = matches[2];
const monthMatch = matches[3];
const weekMatch = matches[4];
const dayMatch = matches[5];
if (yearMatch != null || monthMatch != null || weekMatch != null || dayMatch != null) {
const years = Period._parseNumber(text, yearMatch, negate);
const months = Period._parseNumber(text, monthMatch, negate);
const weeks = Period._parseNumber(text, weekMatch, negate);
let days = Period._parseNumber(text, dayMatch, negate);
days = MathUtil.safeAdd(days, MathUtil.safeMultiply(weeks, 7));
return Period.create(years, months, days);
}
}
throw new DateTimeParseException('Text cannot be parsed to a Period', text, 0);
}
static _parseNumber(text, str, negate) {
if (str == null) {
return 0;
}
const val = MathUtil.parseInt(str);
return MathUtil.safeMultiply(val, negate);
}
//-----------------------------------------------------------------------
/**
* Creates an instance.
*
* @param {number} years - the amount
* @param {number} months - the amount
* @param {number} days - the amount
* @return {Duration}
*/
static create(years, months, days) {
return new Period(years, months, days);
}
//-----------------------------------------------------------------------
/**
* Gets the list of units, from largest to smallest, that fully define this amount.
*
* @returns {ChronoUnit[]} list of units
*/
units() {
return [ChronoUnit.YEARS, ChronoUnit.MONTHS, ChronoUnit.DAYS];
}
/**
* Gets the chronology that defines the meaning of the supported units.
*
* The period is defined by the chronology.
* It controls the supported units and restricts addition/subtraction
* to {@link ChronoLocalDate} instances of the same chronology.
*
* @return {IsoChronology} the chronology defining the period, not null
*/
chronology() {
return IsoChronology.INSTANCE;
}
/**
* Gets the value of the requested unit.
*
* The supported units are chronology specific.
* They will typically be {@link ChronoUnit#YEARS},
* {@link ChronoUnit#MONTHS} and {@link ChronoUnit#DAYS}.
* Requesting an unsupported unit will throw an exception.
*
* @param {TemporalUnit} unit the {@link TemporalUnit} for which to return the value
* @return {number} the long value of the unit
* @throws DateTimeException if the unit is not supported
* @throws UnsupportedTemporalTypeException if the unit is not supported
*/
get(unit) {
if (unit === ChronoUnit.YEARS) {
return this._years;
}
if (unit === ChronoUnit.MONTHS) {
return this._months;
}
if (unit === ChronoUnit.DAYS) {
return this._days;
}
throw new UnsupportedTemporalTypeException(`Unsupported unit: ${unit}`);
}
//-----------------------------------------------------------------------
/**
* Checks if all three units of this period are zero.
*
* A zero period has the value zero for the years, months and days units.
*
* @return {boolean} true if this period is zero-length
*/
isZero() {
return (this === Period.ZERO);
}
/**
* Checks if any of the three units of this period are negative.
*
* This checks whether the years, months or days units are less than zero.
*
* @return {boolean} true if any unit of this period is negative
*/
isNegative() {
return this._years < 0 || this._months < 0 || this._days < 0;
}
//-----------------------------------------------------------------------
/**
* Gets the amount of years of this period.
*
* This returns the years unit.
*
* The months unit is not normalized with the years unit.
* This means that a period of '15 months' is different to a period
* of '1 year and 3 months'.
*
* @return {number} the amount of years of this period, may be negative
*/
years() {
return this._years;
}
/**
* Gets the amount of months of this period.
*
* This returns the months unit.
*
* The months unit is not normalized with the years unit.
* This means that a period of '15 months' is different to a period
* of '1 year and 3 months'.
*
* @return {number} the amount of months of this period, may be negative
*/
months() {
return this._months;
}
/**
* Gets the amount of days of this period.
*
* This returns the days unit.
*
* @return {number} the amount of days of this period, may be negative
*/
days() {
return this._days;
}
//-----------------------------------------------------------------------
/**
* Returns a copy of this period with the specified amount of years.
*
* This sets the amount of the years unit in a copy of this period.
* The months and days units are unaffected.
*
* The months unit is not normalized with the years unit.
* This means that a period of '15 months' is different to a period
* of '1 year and 3 months'.
*
* This instance is immutable and unaffected by this method call.
*
* @param {number} years - the years to represent, may be negative
* @return {Period} a {@link Period} based on this period with the requested years, not null
*/
withYears(years) {
if (years === this._years) {
return this;
}
return Period.create(years, this._months, this._days);
}
/**
* Returns a copy of this period with the specified amount of months.
*
* This sets the amount of the months unit in a copy of this period.
* The years and days units are unaffected.
*
* The months unit is not normalized with the years unit.
* This means that a period of '15 months' is different to a period
* of '1 year and 3 months'.
*
* This instance is immutable and unaffected by this method call.
*
* @param {number} months - the months to represent, may be negative
* @return {Period} a {@link Period} based on this period with the requested months, not null
*/
withMonths(months) {
if (months === this._months) {
return this;
}
return Period.create(this._years, months, this._days);
}
/**
* Returns a copy of this period with the specified amount of days.
*
* This sets the amount of the days unit in a copy of this period.
* The years and months units are unaffected.
*
* This instance is immutable and unaffected by this method call.
*
* @param {number} days - the days to represent, may be negative
* @return {Period} a {@link Period} based on this period with the requested days, not null
*/
withDays(days) {
if (days === this._days) {
return this;
}
return Period.create(this._years, this._months, days);
}
//-----------------------------------------------------------------------
/**
* Returns a copy of this period with the specified amount added.
*
* This input amount is converted to a {@link Period} using {@link from}.
* This operates separately on the years, months and days.
*
* For example, '1 year, 6 months and 3 days' plus '2 years, 2 months and 2 days'
* returns '3 years, 8 months and 5 days'.
*
* This instance is immutable and unaffected by this method call.
*
* @param {TemporalAmount} amountToAdd - the period to add, not null
* @return {Period} a {@link Period} based on this period with the requested period added, not null
* @throws ArithmeticException if numeric overflow occurs
*/
plus(amountToAdd) {
const amount = Period.from(amountToAdd);
return Period.create(
MathUtil.safeAdd(this._years, amount._years),
MathUtil.safeAdd(this._months, amount._months),
MathUtil.safeAdd(this._days, amount._days));
}
/**
* Returns a copy of this period with the specified years added.
*
* This adds the amount to the years unit in a copy of this period.
* The months and days units are unaffected.
* For example, '1 year, 6 months and 3 days' plus 2 years returns '3 years, 6 months and 3 days'.
*
* This instance is immutable and unaffected by this method call.
*
* @param {number} yearsToAdd - the years to add, positive or negative
* @return {Period} a {@link Period} based on this period with the specified years added, not null
* @throws ArithmeticException if numeric overflow occurs
*/
plusYears(yearsToAdd) {
if (yearsToAdd === 0) {
return this;
}
return Period.create(MathUtil.safeToInt(MathUtil.safeAdd(this._years, yearsToAdd)), this._months, this._days);
}
/**
* Returns a copy of this period with the specified months added.
*
* This adds the amount to the months unit in a copy of this period.
* The years and days units are unaffected.
* For example, '1 year, 6 months and 3 days' plus 2 months returns '1 year, 8 months and 3 days'.
*
* This instance is immutable and unaffected by this method call.
*
* @param {number} monthsToAdd - the months to add, positive or negative
* @return {Period} a {@link Period} based on this period with the specified months added, not null
* @throws ArithmeticException if numeric overflow occurs
*/
plusMonths(monthsToAdd) {
if (monthsToAdd === 0) {
return this;
}
return Period.create(this._years, MathUtil.safeToInt(MathUtil.safeAdd(this._months, monthsToAdd)), this._days);
}
/**
* Returns a copy of this period with the specified days added.
*
* This adds the amount to the days unit in a copy of this period.
* The years and months units are unaffected.
* For example, '1 year, 6 months and 3 days' plus 2 days returns '1 year, 6 months and 5 days'.
*
* This instance is immutable and unaffected by this method call.
*
* @param {number} daysToAdd - the days to add, positive or negative
* @return {Period} a {@link Period} based on this period with the specified days added, not null
* @throws ArithmeticException if numeric overflow occurs
*/
plusDays(daysToAdd) {
if (daysToAdd === 0) {
return this;
}
return Period.create(this._years, this._months, MathUtil.safeToInt(MathUtil.safeAdd(this._days, daysToAdd)));
}
//-----------------------------------------------------------------------
/**
* Returns a copy of this period with the specified amount subtracted.
*
* This input amount is converted to a {@link Period} using {@link from}.
* This operates separately on the years, months and days.
*
* For example, '1 year, 6 months and 3 days' minus '2 years, 2 months and 2 days'
* returns '-1 years, 4 months and 1 day'.
*
* This instance is immutable and unaffected by this method call.
*
* @param {TemporalAmount} amountToSubtract - the period to subtract, not null
* @return {Period} a {@link Period} based on this period with the requested period subtracted, not null
* @throws ArithmeticException if numeric overflow occurs
*/
minus(amountToSubtract) {
const amount = Period.from(amountToSubtract);
return Period.create(
MathUtil.safeSubtract(this._years, amount._years),
MathUtil.safeSubtract(this._months, amount._months),
MathUtil.safeSubtract(this._days, amount._days));
}
/**
* Returns a copy of this period with the specified years subtracted.
*
* This subtracts the amount from the years unit in a copy of this period.
* The months and days units are unaffected.
* For example, '1 year, 6 months and 3 days' minus 2 years returns '-1 years, 6 months and 3 days'.
*
* This instance is immutable and unaffected by this method call.
*
* @param {number} yearsToSubtract - the years to subtract, positive or negative
* @return {Period} a {@link Period} based on this period with the specified years subtracted, not null
* @throws ArithmeticException if numeric overflow occurs
*/
minusYears(yearsToSubtract) {
return this.plusYears(-1 * yearsToSubtract);
}
/**
* Returns a copy of this period with the specified months subtracted.
*
* This subtracts the amount from the months unit in a copy of this period.
* The years and days units are unaffected.
* For example, '1 year, 6 months and 3 days' minus 2 months returns '1 year, 4 months and 3 days'.
*
* This instance is immutable and unaffected by this method call.
*
* @param {number} monthsToSubtract - the years to subtract, positive or negative
* @return {Period} a {@link Period} based on this period with the specified months subtracted, not null
* @throws ArithmeticException if numeric overflow occurs
*/
minusMonths(monthsToSubtract) {
return this.plusMonths(-1 * monthsToSubtract);
}
/**
* Returns a copy of this period with the specified days subtracted.
*
* This subtracts the amount from the days unit in a copy of this period.
* The years and months units are unaffected.
* For example, '1 year, 6 months and 3 days' minus 2 days returns '1 year, 6 months and 1 day'.
*
* This instance is immutable and unaffected by this method call.
*
* @param {number} daysToSubtract - the months to subtract, positive or negative
* @return {Period} a {@link Period} based on this period with the specified days subtracted, not null
* @throws ArithmeticException if numeric overflow occurs
*/
minusDays(daysToSubtract) {
return this.plusDays(-1 * daysToSubtract);
}
//-----------------------------------------------------------------------
/**
* Returns a new instance with each element in this period multiplied
* by the specified scalar.
*
* This simply multiplies each field, years, months, days and normalized time,
* by the scalar. No normalization is performed.
*
* @param {number} scalar - the scalar to multiply by, not null
* @return {Period} a {@link Period} based on this period with the amounts multiplied by the scalar, not null
* @throws ArithmeticException if numeric overflow occurs
*/
multipliedBy(scalar) {
if (this === Period.ZERO || scalar === 1) {
return this;
}
return Period.create(
MathUtil.safeMultiply(this._years, scalar),
MathUtil.safeMultiply(this._months, scalar),
MathUtil.safeMultiply(this._days, scalar));
}
/**
* Returns a new instance with each amount in this period negated.
*
* @return {Period} a {@link Period} based on this period with the amounts negated, not null
* @throws ArithmeticException if numeric overflow occurs
*/
negated() {
return this.multipliedBy(-1);
}
//-----------------------------------------------------------------------
/**
* Returns a copy of this period with the years and months normalized
* using a 12 month year.
*
* This normalizes the years and months units, leaving the days unit unchanged.
* The months unit is adjusted to have an absolute value less than 11,
* with the years unit being adjusted to compensate. For example, a period of
* '1 Year and 15 months' will be normalized to '2 years and 3 months'.
*
* The sign of the years and months units will be the same after normalization.
* For example, a period of '1 year and -25 months' will be normalized to
* '-1 year and -1 month'.
*
* This normalization uses a 12 month year which is not valid for all calendar systems.
*
* This instance is immutable and unaffected by this method call.
*
* @return {Period} a {@link Period} based on this period with excess months normalized to years, not null
* @throws ArithmeticException if numeric overflow occurs
*/
normalized() {
const totalMonths = this.toTotalMonths();
const splitYears = MathUtil.intDiv(totalMonths, 12);
const splitMonths = MathUtil.intMod(totalMonths, 12); // no overflow
if (splitYears === this._years && splitMonths === this._months) {
return this;
}
return Period.create(MathUtil.safeToInt(splitYears), splitMonths, this._days);
}
/**
* Gets the total number of months in this period using a 12 month year.
*
* This returns the total number of months in the period by multiplying the
* number of years by 12 and adding the number of months.
*
* This uses a 12 month year which is not valid for all calendar systems.
*
* This instance is immutable and unaffected by this method call.
*
* @return {number} the total number of months in the period, may be negative
*/
toTotalMonths() {
return this._years * 12 + this._months; // no overflow
}
//-------------------------------------------------------------------------
/**
* Adds this period to the specified temporal object.
*
* This returns a temporal object of the same observable type as the input
* with this period added.
*
* In most cases, it is clearer to reverse the calling pattern by using
* {@link Temporal#plus}.
* <pre>
* // these two lines are equivalent, but the second approach is recommended
* dateTime = thisPeriod.addTo(dateTime);
* dateTime = dateTime.plus(thisPeriod);
* </pre>
*
* The calculation will add the years, then months, then days.
* Only non-zero amounts will be added.
* If the date-time has a calendar system with a fixed number of months in a
* year, then the years and months will be combined before being added.
*
* This instance is immutable and unaffected by this method call.
*
* @param {Temporal} temporal - the temporal object to adjust, not null
* @return {Temporal} an object of the same type with the adjustment made, not null
* @throws DateTimeException if unable to add
* @throws ArithmeticException if numeric overflow occurs
*/
addTo(temporal) {
requireNonNull(temporal, 'temporal');
if (this._years !== 0) {
if (this._months !== 0) {
temporal = temporal.plus(this.toTotalMonths(), ChronoUnit.MONTHS);
} else {
temporal = temporal.plus(this._years, ChronoUnit.YEARS);
}
} else if (this._months !== 0) {
temporal = temporal.plus(this._months, ChronoUnit.MONTHS);
}
if (this._days !== 0) {
temporal = temporal.plus(this._days, ChronoUnit.DAYS);
}
return temporal;
}
/**
* Subtracts this period from the specified temporal object.
*
* This returns a temporal object of the same observable type as the input
* with this period subtracted.
*
* In most cases, it is clearer to reverse the calling pattern by using
* {@link Temporal#minus}.
* <pre>
* // these two lines are equivalent, but the second approach is recommended
* dateTime = thisPeriod.subtractFrom(dateTime);
* dateTime = dateTime.minus(thisPeriod);
* </pre>
*
* The calculation operates as follows.
* First, the chronology of the temporal is checked to ensure it is ISO chronology or null.
* Second, if the months are zero, the years are added if non-zero, otherwise
* the combination of years and months is added if non-zero.
* Finally, any days are added.
*
* The calculation will subtract the years, then months, then days.
* Only non-zero amounts will be subtracted.
* If the date-time has a calendar system with a fixed number of months in a
* year, then the years and months will be combined before being subtracted.
*
* This instance is immutable and unaffected by this method call.
*
* @param {Temporal} temporal - the temporal object to adjust, not null
* @return {Temporal} an object of the same type with the adjustment made, not null
* @throws DateTimeException if unable to subtract
* @throws ArithmeticException if numeric overflow occurs
*/
subtractFrom(temporal) {
requireNonNull(temporal, 'temporal');
if (this._years !== 0) {
if (this._months !== 0) {
temporal = temporal.minus(this.toTotalMonths(), ChronoUnit.MONTHS);
} else {
temporal = temporal.minus(this._years, ChronoUnit.YEARS);
}
} else if (this._months !== 0) {
temporal = temporal.minus(this._months, ChronoUnit.MONTHS);
}
if (this._days !== 0) {
temporal = temporal.minus(this._days, ChronoUnit.DAYS);
}
return temporal;
}
//-----------------------------------------------------------------------
/**
* Checks if this period is equal to another period.
*
* The comparison is based on the amounts held in the period.
* To be equal, the years, months and days units must be individually equal.
* Note that this means that a period of '15 Months' is not equal to a period
* of '1 Year and 3 Months'.
*
* @param {*} obj - the object to check, null returns false
* @return {boolean} true if this is equal to the other period
*/
equals(obj) {
if (this === obj) {
return true;
}
if (obj instanceof Period) {
const other = obj;
return this._years === other._years &&
this._months === other._months &&
this._days === other._days;
}
return false;
}
/**
* A hash code for this period.
*
* @return {number} a suitable hash code
*/
hashCode() {
return MathUtil.hashCode(this._years, this._months, this._days);
}
//-----------------------------------------------------------------------
/**
* Outputs this period as a string, such as {@link P6Y3M1D}.
*
* The output will be in the ISO-8601 period format.
* A zero period will be represented as zero days, 'P0D'.
*
* @return {string} a string representation of this period, not null
*/
toString() {
if (this === Period.ZERO) {
return 'P0D';
} else {
let buf = 'P';
if (this._years !== 0) {
buf += `${this._years}Y`;
}
if (this._months !== 0) {
buf += `${this._months}M`;
}
if (this._days !== 0) {
buf += `${this._days}D`;
}
return buf;
}
}
/**
*
* @return {string} same as {@link Period.toString}
*/
toJSON() {
return this.toString();
}
}
export function _init() {
/**
* A constant for a period of zero.
*/
Period.ofDays(0);
}

43
node_modules/@js-joda/core/src/StringUtil.js generated vendored Normal file
View File

@@ -0,0 +1,43 @@
/*
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
import { MathUtil } from './MathUtil';
/**
* @private
*/
export class StringUtil {
/**
*
* @param {string} text
* @param {string} pattern
* @return {boolean}
*/
static startsWith(text, pattern){
return text.indexOf(pattern) === 0;
}
/**
*
* @param {string} text
* @returns {number}
*/
static hashCode(text) {
const len = text.length;
if (len === 0) {
return 0;
}
let hash = 0;
for (let i = 0; i < len; i++) {
const chr = text.charCodeAt(i);
hash = ((hash << 5) - hash) + chr;
hash |= 0; // Convert to 32bit integer
}
return MathUtil.smi(hash);
}
}

933
node_modules/@js-joda/core/src/Year.js generated vendored Normal file
View File

@@ -0,0 +1,933 @@
/**
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
import { DateTimeException, UnsupportedTemporalTypeException } from './errors';
import { requireNonNull, requireInstance } from './assert';
import { MathUtil } from './MathUtil';
import { ChronoField } from './temporal/ChronoField';
import { ChronoUnit } from './temporal/ChronoUnit';
import { Clock } from './Clock';
import { DateTimeFormatter } from './format/DateTimeFormatter';
import { DateTimeFormatterBuilder } from './format/DateTimeFormatterBuilder';
import { IsoChronology } from './chrono/IsoChronology';
import { LocalDate } from './LocalDate';
import { Month } from './Month';
import { MonthDay } from './MonthDay';
import { SignStyle } from './format/SignStyle';
import { Temporal } from './temporal/Temporal';
import { TemporalAccessor } from './temporal/TemporalAccessor';
import { TemporalField } from './temporal/TemporalField';
import { TemporalQueries } from './temporal/TemporalQueries';
import { TemporalQuery, createTemporalQuery } from './temporal/TemporalQuery';
import { TemporalUnit } from './temporal/TemporalUnit';
import { YearConstants } from './YearConstants';
import { YearMonth } from './YearMonth';
import { ZoneId } from './ZoneId';
/**
* A year in the ISO-8601 calendar system, such as `2007`.
*
* {@link Year} is an immutable date-time object that represents a year.
* Any field that can be derived from a year can be obtained.
*
* **Note that years in the ISO chronology only align with years in the
* Gregorian-Julian system for modern years. Parts of Russia did not switch to the
* modern Gregorian/ISO rules until 1920.
* As such, historical years must be treated with caution.**
*
* This class does not store or represent a month, day, time or time-zone.
* For example, the value "2007" can be stored in a {@link Year}.
*
* Years represented by this class follow the ISO-8601 standard and use
* the proleptic numbering system. Year 1 is preceded by year 0, then by year -1.
*
* The ISO-8601 calendar system is the modern civil calendar system used today
* in most of the world. It is equivalent to the proleptic Gregorian calendar
* system, in which today's rules for leap years are applied for all time.
* For most applications written today, the ISO-8601 rules are entirely suitable.
* However, any application that makes use of historical dates, and requires them
* to be accurate will find the ISO-8601 approach unsuitable.
*
* ### Static properties of Class {@link LocalDate}
*
* Year.MIN_VALUE = -999.999;
*
* The minimum supported year. Theoretically the minimum could be -28.542.4812 years in javascript.
* approx LocalDateTime.ofEpochSecond(Number.MIN_SAFE_INTEGER, 0, ZoneOffset.UTC).year()
*
* Year.MAX_VALUE = 999.999;
*
* The maximum supported year. Theoretically the maximum could be 285.428.751 years in javascript.
* approx LocalDateTime.ofEpochSecond(Number.MAX_SAFE_INTEGER, 0, ZoneOffset.UTC).year()
*
*/
export class Year extends Temporal {
/**
*
* @param {number} value
* @private
*/
constructor(value) {
super();
this._year = MathUtil.safeToInt(value);
}
/**
*
* @return {number} gets the value
*/
value() {
return this._year;
}
/**
* function overloading for {@link Year.now}
*
* if called without arguments, then {@link Year.now0} is executed.
* if called with 1 arguments and first argument is an instance of ZoneId, then {@link Year.nowZoneId} is executed.
*
* Otherwise {@link Year.nowClock} is executed.
*
* @param {!(ZoneId|Clock)} zoneIdOrClock
* @returns {Year}
*/
static now(zoneIdOrClock = undefined) {
if (zoneIdOrClock === undefined) {
return Year.now0();
} else if (zoneIdOrClock instanceof ZoneId) {
return Year.nowZoneId(zoneIdOrClock);
} else {
return Year.nowClock(zoneIdOrClock);
}
}
/**
* Obtains the current year from the system clock in the default time-zone.
*
* This will query the system clock (see {@link Clock#systemDefaultZone}) in the default
* time-zone to obtain the current year.
*
* Using this method will prevent the ability to use an alternate clock for testing
* because the clock is hard-coded.
*
* @return {Year} the current year using the system clock and default time-zone, not null
*/
static now0() {
return Year.nowClock(Clock.systemDefaultZone());
}
/**
* Obtains the current year from the system clock in the specified time-zone.
*
* This will query the system clock (see {@link Clock#system}) to obtain the current year.
* Specifying the time-zone avoids dependence on the default time-zone.
*
* Using this method will prevent the ability to use an alternate clock for testing
* because the clock is hard-coded.
*
* @param {ZoneId} zone the zone ID to use, not null
* @return {Year} the current year using the system clock, not null
*/
static nowZoneId(zone) {
requireNonNull(zone, 'zone');
requireInstance(zone, ZoneId, 'zone');
return Year.nowClock(Clock.system(zone));
}
/**
* Obtains the current year from the specified clock.
*
* This will query the specified clock to obtain the current year.
* Using this method allows the use of an alternate clock for testing.
* The alternate clock may be introduced using dependency injection.
*
* @param {Clock} clock the clock to use, not null
* @return {Year} the current year, not null
*/
static nowClock(clock) {
requireNonNull(clock, 'clock');
requireInstance(clock, Clock, 'clock');
const now = LocalDate.now(clock); // called once
return Year.of(now.year());
}
/**
* Obtains an instance of {@link Year}.
*
* This method accepts a year value from the proleptic ISO calendar system.
*
* * The year 2AD/CE is represented by 2.
* * The year 1AD/CE is represented by 1.
* * The year 1BC/BCE is represented by 0.
* * The year 2BC/BCE is represented by -1.
*
* @param {Number} isoYear the ISO proleptic year to represent, from {@link MIN_VALUE} to {@link MAX_VALUE}
* @return {Year} the year, not null
* @throws DateTimeException if the field is invalid
*/
static of(isoYear) {
requireNonNull(isoYear, 'isoYear');
ChronoField.YEAR.checkValidValue(isoYear);
return new Year(isoYear);
}
//-----------------------------------------------------------------------
/**
* Obtains an instance of {@link Year} from a temporal object.
*
* A {@link TemporalAccessor} represents some form of date and time information.
* This factory converts the arbitrary temporal object to an instance of {@link Year}.
*
* The conversion extracts the {@link ChronoField#YEAR} field.
* The extraction is only permitted if the temporal object has an ISO
* chronology, or can be converted to a {@link LocalDate}.
*
* This method matches the signature of the functional interface {@link TemporalQuery}
* allowing it to be used in queries via method reference, {@link Year::from}.
*
* @param {TemporalAccessor} temporal the temporal object to convert, not null
* @return {Year} the year, not null
* @throws DateTimeException if unable to convert to a {@link Year}
*/
static from(temporal) {
requireNonNull(temporal, 'temporal');
requireInstance(temporal, TemporalAccessor, 'temporal');
if (temporal instanceof Year) {
return temporal;
}
try {
/* TODO: we support only ISO for now
if (IsoChronology.INSTANCE.equals(Chronology.from(temporal)) == false) {
temporal = LocalDate.from(temporal);
}*/
return Year.of(temporal.get(ChronoField.YEAR));
} catch (ex) {
throw new DateTimeException(`Unable to obtain Year from TemporalAccessor: ${
temporal}, type ${temporal && temporal.constructor != null ? temporal.constructor.name : ''}`);
}
}
//-----------------------------------------------------------------------
/**
* function overloading for {@link Year.parse}
*
* if called with 1 argument, then {@link Year.parseText} is executed.
*
* Otherwise {@link Year.parseTextFormatter} is executed.
*
* @param {!(String)} text
* @param {?DateTimeFormatter} formatter
* @returns {Year}
*/
static parse(text, formatter) {
if (arguments.length <= 1) {
return Year.parseText(text);
} else {
return Year.parseTextFormatter(text, formatter);
}
}
/**
* Obtains an instance of {@link Year} from a text string such as `2007`.
*
* The string must represent a valid year.
* Years outside the range 0000 to 9999 must be prefixed by the plus or minus symbol.
*
* @param {String} text the text to parse such as "2007", not null
* @return {Year} the parsed year, not null
* @throws DateTimeParseException if the text cannot be parsed
*/
static parseText(text) {
requireNonNull(text, 'text');
return Year.parse(text, PARSER);
}
/**
* Obtains an instance of {@link Year} from a text string using a specific formatter.
*
* The text is parsed using the formatter, returning a year.
*
* @param {String} text the text to parse, not null
* @param {DateTimeFormatter} formatter the formatter to use, not null
* @return {Year} the parsed year, not null
* @throws DateTimeParseException if the text cannot be parsed
*/
static parseTextFormatter(text, formatter = PARSER) {
requireNonNull(text, 'text');
requireNonNull(formatter, 'formatter');
requireInstance(formatter, DateTimeFormatter, 'formatter');
return formatter.parse(text, Year.FROM);
}
//-------------------------------------------------------------------------
/**
* Checks if the year is a leap year, according to the ISO proleptic
* calendar system rules.
*
* This method applies the current rules for leap years across the whole time-line.
* In general, a year is a leap year if it is divisible by four without
* remainder. However, years divisible by 100, are not leap years, with
* the exception of years divisible by 400 which are.
*
* For example, 1904 is a leap year it is divisible by 4.
* 1900 was not a leap year as it is divisible by 100, however 2000 was a
* leap year as it is divisible by 400.
*
* The calculation is proleptic - applying the same rules into the far future and far past.
* This is historically inaccurate, but is correct for the ISO-8601 standard.
*
* @param {number} year the year to check
* @return {boolean} true if the year is leap, false otherwise
*/
static isLeap(year) {
return ((MathUtil.intMod(year, 4) === 0) && ((MathUtil.intMod(year, 100) !== 0) || (MathUtil.intMod(year, 400) === 0)));
}
/**
* function overloading for {@link YearMonth.isSupported}
*
* if called with 1 argument and first argument is an instance of TemporalField, then {@link YearMonth.isSupportedField} is executed,
*
* otherwise {@link YearMonth.isSupportedUnit} is executed
*
* @param {!(TemporalField|ChronoUnit)} fieldOrUnit
* @returns {boolean}
*/
isSupported(fieldOrUnit) {
if (arguments.length === 1 && fieldOrUnit instanceof TemporalField) {
return this.isSupportedField(fieldOrUnit);
} else {
return this.isSupportedUnit(fieldOrUnit);
}
}
/**
* Checks if the specified field is supported.
*
* This checks if this year can be queried for the specified field.
* If false, then calling {@link range} and {@link get} will throw an exception.
*
* If the field is a {@link ChronoField} then the query is implemented here.
* The supported fields (see {@link isSupported}) will return valid
* values based on this date-time.
* The supported fields are:
*
* * {@link YEAR_OF_ERA}
* * {@link YEAR}
* * {@link ERA}
*
* All other {@link ChronoField} instances will return false.
*
* If the field is not a {@link ChronoField}, then the result of this method
* is obtained by invoking {@link TemporalField.isSupportedBy}
* passing `this` as the argument.
* Whether the field is supported is determined by the field.
*
* @param {TemporalField} field the field to check, null returns false
* @return {boolean} true if the field is supported on this year, false if not
*/
isSupportedField(field) {
if (field instanceof ChronoField) {
return field === ChronoField.YEAR || field === ChronoField.YEAR_OF_ERA || field === ChronoField.ERA;
}
return field != null && field.isSupportedBy(this);
}
isSupportedUnit(unit) {
if (unit instanceof ChronoUnit) {
return unit === ChronoUnit.YEARS || unit === ChronoUnit.DECADES || unit === ChronoUnit.CENTURIES || unit === ChronoUnit.MILLENNIA || unit === ChronoUnit.ERAS;
}
return unit != null && unit.isSupportedBy(this);
}
/**
* Gets the range of valid values for the specified field.
*
* The range object expresses the minimum and maximum valid values for a field.
* This year is used to enhance the accuracy of the returned range.
* If it is not possible to return the range, because the field is not supported
* or for some other reason, an exception is thrown.
*
* If the field is a {@link ChronoField} then the query is implemented here.
* The supported fields (see {@link isSupported}) will return
* appropriate range instances.
* All other {@link ChronoField} instances will throw a {@link DateTimeException}.
*
* If the field is not a {@link ChronoField}, then the result of this method
* is obtained by invoking {@link TemporalField.rangeRefinedBy}
* passing `this` as the argument.
* Whether the range can be obtained is determined by the field.
*
* @param {TemporalField} field the field to query the range for, not null
* @return {ValueRange} the range of valid values for the field, not null
* @throws DateTimeException if the range for the field cannot be obtained
*/
range(field) {
if (this.isSupported(field)) {
return field.range();
} else if (field instanceof ChronoField) {
throw new UnsupportedTemporalTypeException(`Unsupported field: ${field}`);
}
return super.range(field);
}
/**
* Gets the value of the specified field from this year as an `int`.
*
* This queries this year for the value for the specified field.
* The returned value will always be within the valid range of values for the field.
* If it is not possible to return the value, because the field is not supported
* or for some other reason, an exception is thrown.
*
* If the field is a {@link ChronoField} then the query is implemented here.
* The supported fields (see {@link isSupported}) will return valid
* values based on this year.
* All other {@link ChronoField} instances will throw a {@link DateTimeException}.
*
* If the field is not a {@link ChronoField}, then the result of this method
* is obtained by invoking {@link TemporalField.getFrom}
* passing `this` as the argument. Whether the value can be obtained,
* and what the value represents, is determined by the field.
*
* @param {TemporalField} field the field to get, not null
* @return {number} the value for the field
* @throws DateTimeException if a value for the field cannot be obtained
* @throws ArithmeticException if numeric overflow occurs
*/
get(field) {
return this.range(field).checkValidIntValue(this.getLong(field), field);
}
/**
* Gets the value of the specified field from this year as a `long`.
*
* This queries this year for the value for the specified field.
* If it is not possible to return the value, because the field is not supported
* or for some other reason, an exception is thrown.
*
* If the field is a {@link ChronoField} then the query is implemented here.
* The supported fields (see {@link isSupported}) will return valid
* values based on this year.
* All other {@link ChronoField} instances will throw a {@link DateTimeException}.
*
* If the field is not a {@link ChronoField}, then the result of this method
* is obtained by invoking {@link TemporalField.getFrom}
* passing `this` as the argument. Whether the value can be obtained,
* and what the value represents, is determined by the field.
*
* @param {TemporalField} field the field to get, not null
* @return {number} the value for the field
* @throws DateTimeException if a value for the field cannot be obtained
* @throws ArithmeticException if numeric overflow occurs
*/
getLong(field) {
requireNonNull(field, 'field');
if (field instanceof ChronoField) {
switch (field) {
case ChronoField.YEAR_OF_ERA: return (this._year < 1 ? 1 - this._year : this._year);
case ChronoField.YEAR: return this._year;
case ChronoField.ERA: return (this._year < 1 ? 0 : 1);
}
throw new UnsupportedTemporalTypeException(`Unsupported field: ${field}`);
}
return field.getFrom(this);
}
//-----------------------------------------------------------------------
/**
* Checks if the year is a leap year, according to the ISO proleptic
* calendar system rules.
*
* This method applies the current rules for leap years across the whole time-line.
* In general, a year is a leap year if it is divisible by four without
* remainder. However, years divisible by 100, are not leap years, with
* the exception of years divisible by 400 which are.
*
* For example, 1904 is a leap year it is divisible by 4.
* 1900 was not a leap year as it is divisible by 100, however 2000 was a
* leap year as it is divisible by 400.
*
* The calculation is proleptic - applying the same rules into the far future and far past.
* This is historically inaccurate, but is correct for the ISO-8601 standard.
*
* @return {boolean} true if the year is leap, false otherwise
*/
isLeap() {
return Year.isLeap(this._year);
}
//-----------------------------------------------------------------------
/**
* Returns a copy of this year with the specified field set to a new value.
*
* This returns a new {@link Year}, based on this one, with the value
* for the specified field changed.
* If it is not possible to set the value, because the field is not supported or for
* some other reason, an exception is thrown.
*
* If the field is a {@link ChronoField} then the adjustment is implemented here.
* The supported fields behave as follows:
*
* * {@link YEAR_OF_ERA} -
* Returns a {@link Year} with the specified year-of-era
* The era will be unchanged.
* * {@link YEAR} -
* Returns a {@link Year} with the specified year.
* This completely replaces the date and is equivalent to {@link of}.
* * {@link ERA} -
* Returns a {@link Year} with the specified era.
* The year-of-era will be unchanged.
*
* In all cases, if the new value is outside the valid range of values for the field
* then a {@link DateTimeException} will be thrown.
*
* All other {@link ChronoField} instances will throw a {@link DateTimeException}.
*
* If the field is not a {@link ChronoField}, then the result of this method
* is obtained by invoking {@link TemporalField.adjustInto}
* passing `this` as the argument. In this case, the field determines
* whether and how to adjust the instant.
*
* This instance is immutable and unaffected by this method call.
*
* @param {TemporalField} field the field to set in the result, not null
* @param {number} newValue the new value of the field in the result
* @returns {Year} based on `this` with the specified field set, not null
* @throws DateTimeException if the field cannot be set
* @throws ArithmeticException if numeric overflow occurs
*/
_withField(field, newValue) {
requireNonNull(field, 'field');
requireInstance(field, TemporalField, 'field');
if (field instanceof ChronoField) {
field.checkValidValue(newValue);
switch (field) {
case ChronoField.YEAR_OF_ERA:
return Year.of((this._year < 1 ? 1 - newValue : newValue));
case ChronoField.YEAR:
return Year.of(newValue);
case ChronoField.ERA:
return (this.getLong(ChronoField.ERA) === newValue ? this : Year.of(1 - this._year));
}
throw new UnsupportedTemporalTypeException(`Unsupported field: ${field}`);
}
return field.adjustInto(this, newValue);
}
/**
* @param {number} amountToAdd
* @param {TemporalUnit} unit
* @return {Year} based on this year with the addition made, not null
* @throws DateTimeException if the addition cannot be made
* @throws ArithmeticException if numeric overflow occurs
*/
_plusUnit(amountToAdd, unit) {
requireNonNull(amountToAdd, 'amountToAdd');
requireNonNull(unit, 'unit');
requireInstance(unit, TemporalUnit, 'unit');
if (unit instanceof ChronoUnit) {
switch (unit) {
case ChronoUnit.YEARS: return this.plusYears(amountToAdd);
case ChronoUnit.DECADES: return this.plusYears(MathUtil.safeMultiply(amountToAdd, 10));
case ChronoUnit.CENTURIES: return this.plusYears(MathUtil.safeMultiply(amountToAdd, 100));
case ChronoUnit.MILLENNIA: return this.plusYears(MathUtil.safeMultiply(amountToAdd, 1000));
case ChronoUnit.ERAS: return this.with(ChronoField.ERA, MathUtil.safeAdd(this.getLong(ChronoField.ERA), amountToAdd));
}
throw new UnsupportedTemporalTypeException(`Unsupported unit: ${unit}`);
}
return unit.addTo(this, amountToAdd);
}
/**
* Returns a copy of this year with the specified number of years added.
*
* This instance is immutable and unaffected by this method call.
*
* @param {number} yearsToAdd the years to add, may be negative
* @return {Year} based on this year with the period added, not null
* @throws DateTimeException if the result exceeds the supported year range
*/
plusYears(yearsToAdd) {
if (yearsToAdd === 0) {
return this;
}
return Year.of(ChronoField.YEAR.checkValidIntValue(MathUtil.safeAdd(this._year, yearsToAdd)));
}
//-----------------------------------------------------------------------
/**
* Returns a copy of this year with the specified number of years subtracted.
*
* This instance is immutable and unaffected by this method call.
*
* @param {number} yearsToSubtract the years to subtract, may be negative
* @return {Year} based on this year with the period subtracted, not null
* @throws DateTimeException if the result exceeds the supported year range
*/
minusYears(yearsToSubtract) {
return (yearsToSubtract === MathUtil.MIN_SAFE_INTEGER ? this.plusYears(MathUtil.MAX_SAFE_INTEGER).plusYears(1) : this.plusYears(-yearsToSubtract));
}
/**
* Adjusts the specified temporal object to have this year.
*
* This returns a temporal object of the same observable type as the input
* with the year changed to be the same as this.
*
* The adjustment is equivalent to using {@link Temporal#with}
* passing {@link ChronoField#YEAR} as the field.
* If the specified temporal object does not use the ISO calendar system then
* a {@link DateTimeException} is thrown.
*
* In most cases, it is clearer to reverse the calling pattern by using
* {@link Temporal#with}:
* <pre>
* // these two lines are equivalent, but the second approach is recommended
* temporal = thisYear.adjustInto(temporal);
* temporal = temporal.with(thisYear);
* </pre>
*
* This instance is immutable and unaffected by this method call.
*
* @param {Temporal} temporal the target object to be adjusted, not null
* @return {Temporal} the adjusted object, not null
* @throws DateTimeException if unable to make the adjustment
* @throws ArithmeticException if numeric overflow occurs
*/
adjustInto(temporal) {
requireNonNull(temporal, 'temporal');
/* TODO: only IsoChronology for now
if (Chronology.from(temporal).equals(IsoChronology.INSTANCE) == false) {
throw new DateTimeException("Adjustment only supported on ISO date-time");
}*/
return temporal.with(ChronoField.YEAR, this._year);
}
/**
* Checks if the month-day is valid for this year.
*
* This method checks whether this year and the input month and day form
* a valid date.
*
* @param {MonthDay} monthDay the month-day to validate, null returns false
* @return {boolean} true if the month and day are valid for this year
*/
isValidMonthDay(monthDay) {
return monthDay != null && monthDay.isValidYear(this._year);
}
/**
* Gets the length of this year in days.
*
* @return {number} the length of this year in days, 365 or 366
*/
length() {
return this.isLeap() ? 366 : 365;
}
//-----------------------------------------------------------------------
/**
* Combines this year with a day-of-year to create a {@link LocalDate}.
*
* This returns a {@link LocalDate} formed from this year and the specified day-of-year.
*
* The day-of-year value 366 is only valid in a leap year.
*
* @param {number} dayOfYear the day-of-year to use, not null
* @return {LocalDate} the local date formed from this year and the specified date of year, not null
* @throws DateTimeException if the day of year is zero or less, 366 or greater or equal
* to 366 and this is not a leap year
*/
atDay(dayOfYear) {
return LocalDate.ofYearDay(this._year, dayOfYear);
}
/**
* function overloading for {@link Year.atMonth}
*
* if called with 1 arguments and first argument is instance of Month, then {@link Year.atMonthMonth} is executed.
*
* Otherwise {@link Year.atMonthNumber} is executed.
*
* @param {Month|number} monthOrNumber
* @returns {YearMonth}
*/
atMonth(monthOrNumber) {
if (arguments.length === 1 && monthOrNumber instanceof Month) {
return this.atMonthMonth(monthOrNumber);
} else {
return this.atMonthNumber(monthOrNumber);
}
}
/**
* Combines this year with a month to create a {@link YearMonth}.
*
* This returns a {@link YearMonth} formed from this year and the specified month.
* All possible combinations of year and month are valid.
*
* This method can be used as part of a chain to produce a date:
* <pre>
* LocalDate date = year.atMonth(month).atDay(day);
* </pre>
*
* @param {Month} month the month-of-year to use, not null
* @return {YearMonth} the year-month formed from this year and the specified month, not null
*/
atMonthMonth(month) {
requireNonNull(month, 'month');
requireInstance(month, Month, 'month');
return YearMonth.of(this._year, month);
}
/**
* Combines this year with a month to create a {@link YearMonth}.
*
* This returns a {@link YearMonth} formed from this year and the specified month.
* All possible combinations of year and month are valid.
*
* This method can be used as part of a chain to produce a date:
* <pre>
* LocalDate date = year.atMonth(month).atDay(day);
* </pre>
*
* @param {number} month the month-of-year to use, from 1 (January) to 12 (December)
* @return {YearMonth} the year-month formed from this year and the specified month, not null
* @throws DateTimeException if the month is invalid
*/
atMonthNumber(month) {
requireNonNull(month, 'month');
return YearMonth.of(this._year, month);
}
/**
* Combines this year with a month-day to create a {@link LocalDate}.
*
* This returns a {@link LocalDate} formed from this year and the specified month-day.
*
* A month-day of February 29th will be adjusted to February 28th in the resulting
* date if the year is not a leap year.
*
* @param {MonthDay} monthDay the month-day to use, not null
* @return {LocalDate} the local date formed from this year and the specified month-day, not null
*/
atMonthDay(monthDay) {
requireNonNull(monthDay, 'monthDay');
requireInstance(monthDay, MonthDay, 'monthDay');
return monthDay.atYear(this._year);
}
//-----------------------------------------------------------------------
/**
* Queries this year using the specified query.
*
* This queries this year using the specified query strategy object.
* The {@link TemporalQuery} object defines the logic to be used to
* obtain the result. Read the documentation of the query to understand
* what the result of this method will be.
*
* The result of this method is obtained by invoking the
* {@link TemporalQuery#queryFrom} method on the
* specified query passing `this` as the argument.
*
* @param {TemporalQuery} query the query to invoke, not null
* @return {*} the query result, null may be returned (defined by the query)
* @throws DateTimeException if unable to query (defined by the query)
* @throws ArithmeticException if numeric overflow occurs (defined by the query)
*/
query(query) {
requireNonNull(query, 'query()');
requireInstance(query, TemporalQuery, 'query()');
if (query === TemporalQueries.chronology()) {
return IsoChronology.INSTANCE;
} else if (query === TemporalQueries.precision()) {
return ChronoUnit.YEARS;
} else if (query === TemporalQueries.localDate() || query === TemporalQueries.localTime() ||
query === TemporalQueries.zone() || query === TemporalQueries.zoneId() || query === TemporalQueries.offset()) {
return null;
}
return super.query(query);
}
//-----------------------------------------------------------------------
/**
* Compares this year to another year.
*
* The comparison is based on the value of the year.
* It is "consistent with equals", as defined by {@link Comparable}.
*
* @param {Year} other the other year to compare to, not null
* @return {number} the comparator value, negative if less, positive if greater
*/
compareTo(other) {
requireNonNull(other, 'other');
requireInstance(other, Year, 'other');
return this._year - other._year;
}
/**
* Is this year after the specified year.
*
* @param {Year} other the other year to compare to, not null
* @return {boolean} true if this is after the specified year
*/
isAfter(other) {
requireNonNull(other, 'other');
requireInstance(other, Year, 'other');
return this._year > other._year;
}
/**
* Is this year before the specified year.
*
* @param {Year} other the other year to compare to, not null
* @return {boolean} true if this point is before the specified year
*/
isBefore(other) {
requireNonNull(other, 'other');
requireInstance(other, Year, 'other');
return this._year < other._year;
}
/**
* Outputs this year as a string using the formatter.
*
* @param {DateTimeFormatter} formatter the formatter to use, not null
* @return {String} the formatted year string, not null
* @throws DateTimeException if an error occurs during printing
*/
format(formatter) {
requireNonNull(formatter, 'formatter');
requireInstance(formatter, DateTimeFormatter, 'formatter');
return formatter.format(this);
}
/**
* Checks if this year is equal to the specified {@link Year}.
*
* The comparison is based on the value
*
* @param {*} other - the other year, null returns false
* @return {boolean} true if the other duration is equal to this one
*/
equals(other) {
if (this === other) {
return true;
}
if (other instanceof Year) {
return this.value() === other.value();
}
return false;
}
/**
* Outputs this year as a string.
*
* @return {String} a string representation of this year, not null
*/
toString() {
return `${this._year}`;
}
/**
* toJSON() use by JSON.stringify
* delegates to toString()
*
* @return {string}
*/
toJSON() {
return this.toString();
}
/**
* Calculates the amount of time until another temporal in terms of the specified unit.
* This calculates the amount of time between two temporal objects in terms of a single {@link TemporalUnit}. The start and end points are this and the specified temporal. The end point is converted to be of the same type as the start point if different. The result will be negative if the end is before the start. For example, the amount in hours between two temporal objects can be calculated using `startTime.until(endTime, HOURS)`.
*
* The calculation returns a whole number, representing the number of complete units between the two temporals. For example, the amount in hours between the times 11:30 and 13:29 will only be one hour as it is one minute short of two hours.
*
* There are two equivalent ways of using this method. The first is to invoke this method directly. The second is to use `TemporalUnit.between(Temporal, Temporal)`:
*
* <pre>
* // these two lines are equivalent
* temporal = start.until(end, unit);
* temporal = unit.between(start, end);
* </pre>
*
* The choice should be made based on which makes the code more readable.
* For example, this method allows the number of days between two dates to be calculated:
*
* <pre>
* daysBetween = start.until(end, DAYS);
* // or alternatively
* daysBetween = DAYS.between(start, end);
* </pre>
*
* ### Implementation Requirements:
* Implementations must begin by checking to ensure that the input temporal object is of the same observable type as the implementation. They must then perform the calculation for all instances of {@link ChronoUnit}. An {@link UnsupportedTemporalTypeException} must be thrown for {@link ChronoUnit} instances that are unsupported.
* If the unit is not a {@link ChronoUnit}, then the result of this method is obtained by invoking `TemporalUnit.between(Temporal, Temporal)` passing this as the first argument and the converted input temporal as the second argument.
*
* In summary, implementations must behave in a manner equivalent to this pseudo-code:
*
* <pre>
* // convert the end temporal to the same type as this class
* if (unit instanceof ChronoUnit) {
* // if unit is supported, then calculate and return result
* // else throw UnsupportedTemporalTypeException for unsupported units
* }
* return unit.between(this, convertedEndTemporal);
* </pre>
*
* Note that the unit's between method must only be invoked if the two temporal objects have exactly the same type evaluated by `getClass()`.
*
* Implementations must ensure that no observable state is altered when this read-only method is invoked.
*
* @param {Temporal} endExclusive - the end temporal, exclusive, converted to be of the same type as this object, not null
* @param {TemporalUnit} unit - the unit to measure the amount in, not null
* @return {number} the amount of time between this temporal object and the specified one in terms of the unit; positive if the specified object is later than this one, negative if it is earlier than this one
* @throws DateTimeException - if the amount cannot be calculated, or the end temporal cannot be converted to the same type as this temporal
* @throws UnsupportedTemporalTypeException - if the unit is not supported
* @throws ArithmeticException - if numeric overflow occurs
*/
until(endExclusive, unit) {
const end = Year.from(endExclusive);
if (unit instanceof ChronoUnit) {
const yearsUntil = end.value() - this.value();
switch (unit) {
case ChronoUnit.YEARS:
return yearsUntil;
case ChronoUnit.DECADES:
return MathUtil.intDiv(yearsUntil, 10);
case ChronoUnit.CENTURIES:
return MathUtil.intDiv(yearsUntil, 100);
case ChronoUnit.MILLENNIA:
return MathUtil.intDiv(yearsUntil, 1000);
case ChronoUnit.ERAS:
return end.getLong(ChronoField.ERA) - this.getLong(ChronoField.ERA);
}
throw new UnsupportedTemporalTypeException(`Unsupported unit: ${unit}`);
}
return unit.between(this, end);
}
}
let PARSER;
export function _init() {
Year.MIN_VALUE = YearConstants.MIN_VALUE;
Year.MAX_VALUE = YearConstants.MAX_VALUE;
PARSER = new DateTimeFormatterBuilder()
.appendValue(ChronoField.YEAR, 4, 10, SignStyle.EXCEEDS_PAD)
.toFormatter();
Year.FROM = createTemporalQuery('Year.FROM', (temporal) => {
return Year.from(temporal);
});
}

21
node_modules/@js-joda/core/src/YearConstants.js generated vendored Normal file
View File

@@ -0,0 +1,21 @@
/*
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @license BSD-3-Clause (see LICENSE.md in the root directory of this source tree)
*/
/**
* attempt to avoid dependency cycles... define all constants here and they could be used
* so instead of using e.g. Year.MAX_VALUE we could use YearConstants.MAX_VALUE to avoid the cycle
*/
export class YearConstants {}
export function _init() {
/**
* The minimum supported year
*/
YearConstants.MIN_VALUE = -999999;
/**
* The maximum supported year
*/
YearConstants.MAX_VALUE = 999999;
}

1015
node_modules/@js-joda/core/src/YearMonth.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

236
node_modules/@js-joda/core/src/ZoneId.js generated vendored Normal file
View File

@@ -0,0 +1,236 @@
/*
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
import { abstractMethodFail } from './assert';
import { DateTimeException } from './errors';
import { StringUtil } from './StringUtil';
import { Instant } from './Instant';
export class ZoneId {
/**
* Gets the system default time-zone.
*
* @return {ZoneId} the zone ID, not null
*/
static systemDefault() {
// Find implementation at {@link ZoneIdFactory}
throw new DateTimeException('not supported operation');
}
/**
* Gets the set of available zone IDs.
*
* This set includes the string form of all available region-based IDs.
* Offset-based zone IDs are not included in the returned set.
* The ID can be passed to {@link of} to create a {@link ZoneId}.
*
* The set of zone IDs can increase over time, although in a typical application
* the set of IDs is fixed. Each call to this method is thread-safe.
*
* @return {string[]} a modifiable copy of the set of zone IDs, not null
*/
static getAvailableZoneIds() {
// Find implementation at {@link ZoneIdFactory}
throw new DateTimeException('not supported operation');
}
/**
* Obtains an instance of {@link ZoneId} from an ID ensuring that the
* ID is valid and available for use.
*
* This method parses the ID producing a {@link ZoneId} or {@link ZoneOffset}.
* A {@link ZoneOffset} is returned if the ID is 'Z', or starts with '+' or '-'.
* The result will always be a valid ID for which {@link ZoneRules} can be obtained.
*
* Parsing matches the zone ID step by step as follows.
*
* * If the zone ID equals 'Z', the result is {@link ZoneOffset.UTC}.
* * If the zone ID consists of a single letter, the zone ID is invalid
* and {@link DateTimeException} is thrown.
* * If the zone ID starts with '+' or '-', the ID is parsed as a
* {@link ZoneOffset} using {@link ZoneOffset#of}.
* * If the zone ID equals 'GMT', 'UTC' or 'UT' then the result is a {@link ZoneId}
* with the same ID and rules equivalent to {@link ZoneOffset.UTC}.
* * If the zone ID starts with 'UTC+', 'UTC-', 'GMT+', 'GMT-', 'UT+' or 'UT-'
* then the ID is a prefixed offset-based ID. The ID is split in two, with
* a two or three letter prefix and a suffix starting with the sign.
* The suffix is parsed as a {@link ZoneOffset}.
* The result will be a {@link ZoneId} with the specified UTC/GMT/UT prefix
* and the normalized offset ID as per {@link ZoneOffset#getId}.
* The rules of the returned {@link ZoneId} will be equivalent to the
* parsed {@link ZoneOffset}.
* * All other IDs are parsed as region-based zone IDs. Region IDs must
* match the regular expression `[A-Za-z][A-Za-z0-9~/._+-]+`,
* otherwise a {@link DateTimeException} is thrown. If the zone ID is not
* in the configured set of IDs, {@link ZoneRulesException} is thrown.
* The detailed format of the region ID depends on the group supplying the data.
* The default set of data is supplied by the IANA Time Zone Database (TZDB).
* This has region IDs of the form '{area}/{city}', such as 'Europe/Paris' or 'America/New_York'.
* This is compatible with most IDs from {@link java.util.TimeZone}.
*
* @param {string} zoneId the time-zone ID, not null
* @return {ZoneId} the zone ID, not null
* @throws DateTimeException if the zone ID has an invalid format
* @throws ZoneRulesException if the zone ID is a region ID that cannot be found
*/
static of(zoneId) {
// Find implementation at {@link ZoneIdFactory}
throw new DateTimeException(`not supported operation${zoneId}`);
}
/**
* Obtains an instance of {@link ZoneId} wrapping an offset.
*
* If the prefix is 'GMT', 'UTC', or 'UT' a {@link ZoneId}
* with the prefix and the non-zero offset is returned.
* If the prefix is empty `''` the {@link ZoneOffset} is returned.
*
* @param {string} prefix the time-zone ID, not null
* @param {ZoneOffset} offset the offset, not null
* @return {ZoneId} the zone ID, not null
* @throws IllegalArgumentException if the prefix is not one of
* 'GMT', 'UTC', or 'UT', or ''
*/
static ofOffset(prefix, offset) {
// Find implementation at {@link ZoneIdFactory}
throw new DateTimeException(`not supported operation${prefix}${offset}`);
}
/**
* Obtains an instance of {@link ZoneId} from a temporal object.
*
* A {@link TemporalAccessor} represents some form of date and time information.
* This factory converts the arbitrary temporal object to an instance of {@link ZoneId}.
*
* The conversion will try to obtain the zone in a way that favours region-based
* zones over offset-based zones using {@link TemporalQueries#zone}.
*
* This method matches the signature of the functional interface {@link TemporalQuery}
* allowing it to be used in queries via method reference, {@link ZoneId::from}.
*
* @param {!TemporalAccessor} temporal - the temporal object to convert, not null
* @return {ZoneId} the zone ID, not null
* @throws DateTimeException if unable to convert to a {@link ZoneId}
*/
static from(temporal) {
// Find implementation at {@link ZoneIdFactory}
throw new DateTimeException(`not supported operation${temporal}`);
}
//-----------------------------------------------------------------------
/**
* Gets the unique time-zone ID.
*
* This ID uniquely defines this object.
* The format of an offset based ID is defined by {@link ZoneOffset#getId}.
*
* @return {String} the time-zone unique ID, not null
*/
id(){
abstractMethodFail('ZoneId.id');
}
//-----------------------------------------------------------------------
/**
* Gets the time-zone rules for this ID allowing calculations to be performed.
*
* The rules provide the functionality associated with a time-zone,
* such as finding the offset for a given instant or local date-time.
*
* A time-zone can be invalid if it is deserialized in a Java Runtime which
* does not have the same rules loaded as the Java Runtime that stored it.
* In this case, calling this method will throw a {@link ZoneRulesException}.
*
* The rules are supplied by {@link ZoneRulesProvider}. An advanced provider may
* support dynamic updates to the rules without restarting the Java Runtime.
* If so, then the result of this method may change over time.
* Each individual call will be still remain thread-safe.
*
* {@link ZoneOffset} will always return a set of rules where the offset never changes.
*
* @return {!ZoneRules} the rules, not null
* @throws ZoneRulesException if no rules are available for this ID
*/
rules(){
abstractMethodFail('ZoneId.rules');
}
/**
* Normalizes the time-zone ID, returning a {@link ZoneOffset} where possible.
*
* The returns a normalized {@link ZoneId} that can be used in place of this ID.
* The result will have {@link ZoneRules} equivalent to those returned by this object,
* however the ID returned by {@link getId} may be different.
*
* The normalization checks if the rules of this {@link ZoneId} have a fixed offset.
* If they do, then the {@link ZoneOffset} equal to that offset is returned.
* Otherwise `this` is returned.
*
* @return {ZoneId} the time-zone unique ID, not null
*/
normalized() {
const rules = this.rules();
if (rules.isFixedOffset()) {
return rules.offset(Instant.EPOCH);
}
//try {
//} catch (ZoneRulesException ex) {
// // ignore invalid objects
//}
return this;
}
//-----------------------------------------------------------------------
/**
* Checks if this time-zone ID is equal to another time-zone ID.
*
* The comparison is based on the ID.
*
* @param {*} other the object to check, null returns false
* @return {boolean} true if this is equal to the other time-zone ID
*/
equals(other) {
if (this === other) {
return true;
}
if (other instanceof ZoneId) {
return this.id() === other.id();
}
return false;
}
/**
* A hash code for this time-zone ID.
*
* @return {number} a suitable hash code
*/
hashCode() {
return StringUtil.hashCode(this.id());
}
//-----------------------------------------------------------------------
/**
* Outputs this zone as a string, using the ID.
*
* @return {string} a string representation of this time-zone ID, not null
*/
toString() {
return this.id();
}
/**
* toJSON() use by JSON.stringify
* delegates to toString()
*
* @return {string}
*/
toJSON() {
return this.toString();
}
}

201
node_modules/@js-joda/core/src/ZoneIdFactory.js generated vendored Normal file
View File

@@ -0,0 +1,201 @@
/*
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
import { requireNonNull } from './assert';
import { DateTimeException, IllegalArgumentException } from './errors';
import { StringUtil } from './StringUtil';
import { ZoneOffset } from './ZoneOffset';
import { ZoneRegion } from './ZoneRegion';
import { ZoneId } from './ZoneId';
import { TemporalQueries } from './temporal/TemporalQueries';
import { SystemDefaultZoneId } from './zone/SystemDefaultZoneId';
import { ZoneRulesProvider } from './zone/ZoneRulesProvider';
/**
* @see {@link ZoneId}
*
* Helper class to avoid dependency cycles.
* Static methods of the class ZoneIdFactory are added automatically to class ZoneId.
* @private
*/
export class ZoneIdFactory {
/**
* Gets the system default time-zone.
*
*
* @return {ZoneId} the zone ID, not null
*/
static systemDefault() {
return SYSTEM_DEFAULT_ZONE_ID_INSTANCE;
}
/**
* Gets the set of available zone IDs.
*
* This set includes the string form of all available region-based IDs.
* Offset-based zone IDs are not included in the returned set.
* The ID can be passed to {@link of} to create a {@link ZoneId}.
*
* The set of zone IDs can increase over time, although in a typical application
* the set of IDs is fixed. Each call to this method is thread-safe.
*
* @return {string[]} a modifiable copy of the set of zone IDs, not null
*/
static getAvailableZoneIds() {
return ZoneRulesProvider.getAvailableZoneIds();
}
/**
* Obtains an instance of {@link ZoneId} from an ID ensuring that the
* ID is valid and available for use.
*
* This method parses the ID producing a {@link ZoneId} or {@link ZoneOffset}.
* A {@link ZoneOffset} is returned if the ID is 'Z', or starts with '+' or '-'.
* The result will always be a valid ID for which {@link ZoneRules} can be obtained.
*
* Parsing matches the zone ID step by step as follows.
*
* * If the zone ID equals 'Z', the result is {@link ZoneOffset.UTC}.
* * If the zone ID consists of a single letter, the zone ID is invalid
* and {@link DateTimeException} is thrown.
* * If the zone ID starts with '+' or '-', the ID is parsed as a
* {@link ZoneOffset} using {@link ZoneOffset#of}.
* * If the zone ID equals 'GMT', 'UTC' or 'UT' then the result is a {@link ZoneId}
* with the same ID and rules equivalent to {@link ZoneOffset.UTC}.
* * If the zone ID starts with 'UTC+', 'UTC-', 'GMT+', 'GMT-', 'UT+' or 'UT-'
* then the ID is a prefixed offset-based ID. The ID is split in two, with
* a two or three letter prefix and a suffix starting with the sign.
* The suffix is parsed as a {@link ZoneOffset}.
* The result will be a {@link ZoneId} with the specified UTC/GMT/UT prefix
* and the normalized offset ID as per {@link ZoneOffset#getId}.
* The rules of the returned {@link ZoneId} will be equivalent to the
* parsed {@link ZoneOffset}.
* * All other IDs are parsed as region-based zone IDs. Region IDs must
* match the regular expression `[A-Za-z][A-Za-z0-9~/._+-]+`,
* otherwise a {@link DateTimeException} is thrown. If the zone ID is not
* in the configured set of IDs, {@link ZoneRulesException} is thrown.
* The detailed format of the region ID depends on the group supplying the data.
* The default set of data is supplied by the IANA Time Zone Database (TZDB).
* This has region IDs of the form '{area}/{city}', such as 'Europe/Paris' or 'America/New_York'.
* This is compatible with most IDs from {@link java.util.TimeZone}.
*
* @param {string} zoneId the time-zone ID, not null
* @return {ZoneId} the zone ID, not null
* @throws DateTimeException if the zone ID has an invalid format
* @throws ZoneRulesException if the zone ID is a region ID that cannot be found
*/
static of(zoneId) {
requireNonNull(zoneId, 'zoneId');
if (zoneId === 'Z') {
return ZoneOffset.UTC;
}
if (zoneId.length === 1) {
throw new DateTimeException(`Invalid zone: ${zoneId}`);
}
if (StringUtil.startsWith(zoneId, '+') || StringUtil.startsWith(zoneId, '-')) {
return ZoneOffset.of(zoneId);
}
if (zoneId === 'UTC' || zoneId === 'GMT' || zoneId === 'GMT0' || zoneId === 'UT') {
return new ZoneRegion(zoneId, ZoneOffset.UTC.rules());
}
if (StringUtil.startsWith(zoneId, 'UTC+') || StringUtil.startsWith(zoneId, 'GMT+') ||
StringUtil.startsWith(zoneId, 'UTC-') || StringUtil.startsWith(zoneId, 'GMT-')) {
const offset = ZoneOffset.of(zoneId.substring(3));
if (offset.totalSeconds() === 0) {
return new ZoneRegion(zoneId.substring(0, 3), offset.rules());
}
return new ZoneRegion(zoneId.substring(0, 3) + offset.id(), offset.rules());
}
if (StringUtil.startsWith(zoneId, 'UT+') || StringUtil.startsWith(zoneId, 'UT-')) {
const offset = ZoneOffset.of(zoneId.substring(2));
if (offset.totalSeconds() === 0) {
return new ZoneRegion('UT', offset.rules());
}
return new ZoneRegion(`UT${offset.id()}`, offset.rules());
}
// javascript special case
if(zoneId === 'SYSTEM'){
return ZoneId.systemDefault();
}
return ZoneRegion.ofId(zoneId);
}
/**
* Obtains an instance of {@link ZoneId} wrapping an offset.
*
* If the prefix is 'GMT', 'UTC', or 'UT' a {@link ZoneId}
* with the prefix and the non-zero offset is returned.
* If the prefix is empty `''` the {@link ZoneOffset} is returned.
*
* @param {string} prefix the time-zone ID, not null
* @param {ZoneOffset} offset the offset, not null
* @return {ZoneId} the zone ID, not null
* @throws IllegalArgumentException if the prefix is not one of
* 'GMT', 'UTC', or 'UT', or ''
*/
static ofOffset(prefix, offset) {
requireNonNull(prefix, 'prefix');
requireNonNull(offset, 'offset');
if (prefix.length === 0) {
return offset;
}
if (prefix === 'GMT' || prefix === 'UTC' || prefix === 'UT') {
if (offset.totalSeconds() === 0) {
return new ZoneRegion(prefix, offset.rules());
}
return new ZoneRegion(prefix + offset.id(), offset.rules());
}
throw new IllegalArgumentException(`Invalid prefix, must be GMT, UTC or UT: ${prefix}`);
}
/**
* Obtains an instance of {@link ZoneId} from a temporal object.
*
* A {@link TemporalAccessor} represents some form of date and time information.
* This factory converts the arbitrary temporal object to an instance of {@link ZoneId}.
*
* The conversion will try to obtain the zone in a way that favours region-based
* zones over offset-based zones using {@link TemporalQueries#zone}.
*
* This method matches the signature of the functional interface {@link TemporalQuery}
* allowing it to be used in queries via method reference, {@link ZoneId::from}.
*
* @param {!TemporalAccessor} temporal - the temporal object to convert, not null
* @return {ZoneId} the zone ID, not null
* @throws DateTimeException if unable to convert to a {@link ZoneId}
*/
static from(temporal) {
requireNonNull(temporal, 'temporal');
const obj = temporal.query(TemporalQueries.zone());
if (obj == null) {
throw new DateTimeException(`Unable to obtain ZoneId from TemporalAccessor: ${
temporal}, type ${temporal.constructor != null ? temporal.constructor.name : ''}`);
}
return obj;
}
}
let SYSTEM_DEFAULT_ZONE_ID_INSTANCE = null;
export function _init(){
SYSTEM_DEFAULT_ZONE_ID_INSTANCE = new SystemDefaultZoneId();
// a bit magic to stay a bit more to the threeten bp impl.
ZoneId.systemDefault = ZoneIdFactory.systemDefault;
ZoneId.getAvailableZoneIds = ZoneIdFactory.getAvailableZoneIds;
ZoneId.of = ZoneIdFactory.of;
ZoneId.ofOffset = ZoneIdFactory.ofOffset;
ZoneId.from = ZoneIdFactory.from;
ZoneOffset.from = ZoneIdFactory.from;
// short cut
ZoneId.SYSTEM = SYSTEM_DEFAULT_ZONE_ID_INSTANCE;
ZoneId.UTC = ZoneOffset.ofTotalSeconds(0);
}

486
node_modules/@js-joda/core/src/ZoneOffset.js generated vendored Normal file
View File

@@ -0,0 +1,486 @@
/**
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
import { requireNonNull } from './assert';
import { DateTimeException } from './errors';
import { MathUtil } from './MathUtil';
import { LocalTime } from './LocalTime';
import { ZoneId } from './ZoneId';
import { ChronoField } from './temporal/ChronoField';
import { TemporalQueries } from './temporal/TemporalQueries';
import { ZoneRules } from './zone/ZoneRules';
const SECONDS_CACHE = {};
const ID_CACHE = {};
/**
*
* ### Static properties of Class {@link LocalDate}
*
* ZoneOffset.MAX_SECONDS = 18 * LocalTime.SECONDS_PER_HOUR;
*
* ZoneOffset.UTC = ZoneOffset.ofTotalSeconds(0);
*
* ZoneOffset.MIN = ZoneOffset.ofTotalSeconds(-ZoneOffset.MAX_SECONDS);
*
* ZoneOffset.MAX = ZoneOffset.ofTotalSeconds(ZoneOffset.MAX_SECONDS);
*
*/
export class ZoneOffset extends ZoneId {
/**
*
* @param {number} totalSeconds
* @private
*/
constructor(totalSeconds){
super();
ZoneOffset._validateTotalSeconds(totalSeconds);
this._totalSeconds = MathUtil.safeToInt(totalSeconds);
this._rules = ZoneRules.of(this);
this._id = ZoneOffset._buildId(totalSeconds);
}
/**
*
* @returns {number}
*/
totalSeconds() {
return this._totalSeconds;
}
/**
*
* @returns {string}
*/
id() {
return this._id;
}
/**
*
* @param {number} totalSeconds
* @returns {string}
*/
static _buildId(totalSeconds) {
if (totalSeconds === 0) {
return 'Z';
} else {
const absTotalSeconds = Math.abs(totalSeconds);
const absHours = MathUtil.intDiv(absTotalSeconds, LocalTime.SECONDS_PER_HOUR);
const absMinutes = MathUtil.intMod(MathUtil.intDiv(absTotalSeconds, LocalTime.SECONDS_PER_MINUTE), LocalTime.MINUTES_PER_HOUR);
let buf = `${totalSeconds < 0 ? '-' : '+'
}${absHours < 10 ? '0' : ''}${absHours
}${absMinutes < 10 ? ':0' : ':'}${absMinutes}`;
const absSeconds = MathUtil.intMod(absTotalSeconds, LocalTime.SECONDS_PER_MINUTE);
if (absSeconds !== 0) {
buf += (absSeconds < 10 ? ':0' : ':') + (absSeconds);
}
return buf;
}
}
/**
*
* @param {number} totalSeconds
* @private
*/
static _validateTotalSeconds(totalSeconds){
if (Math.abs(totalSeconds) > ZoneOffset.MAX_SECONDS) {
throw new DateTimeException('Zone offset not in valid range: -18:00 to +18:00');
}
}
/**
*
* @param {number} hours
* @param {number} minutes
* @param {number} seconds
* @private
*/
static _validate(hours, minutes, seconds) {
if (hours < -18 || hours > 18) {
throw new DateTimeException(`Zone offset hours not in valid range: value ${hours
} is not in the range -18 to 18`);
}
if (hours > 0) {
if (minutes < 0 || seconds < 0) {
throw new DateTimeException('Zone offset minutes and seconds must be positive because hours is positive');
}
} else if (hours < 0) {
if (minutes > 0 || seconds > 0) {
throw new DateTimeException('Zone offset minutes and seconds must be negative because hours is negative');
}
} else if ((minutes > 0 && seconds < 0) || (minutes < 0 && seconds > 0)) {
throw new DateTimeException('Zone offset minutes and seconds must have the same sign');
}
if (Math.abs(minutes) > 59) {
throw new DateTimeException(`Zone offset minutes not in valid range: abs(value) ${
Math.abs(minutes)} is not in the range 0 to 59`);
}
if (Math.abs(seconds) > 59) {
throw new DateTimeException(`Zone offset seconds not in valid range: abs(value) ${
Math.abs(seconds)} is not in the range 0 to 59`);
}
if (Math.abs(hours) === 18 && (Math.abs(minutes) > 0 || Math.abs(seconds) > 0)) {
throw new DateTimeException('Zone offset not in valid range: -18:00 to +18:00');
}
}
//-----------------------------------------------------------------------
/**
* Obtains an instance of {@link ZoneOffset} using the ID.
*
* This method parses the string ID of a {@link ZoneOffset} to
* return an instance. The parsing accepts all the formats generated by
* {@link getId}, plus some additional formats:
*
* * {@link Z} - for UTC
* * `+h`
* * `+hh`
* * `+hh:mm`
* * `-hh:mm`
* * `+hhmm`
* * `-hhmm`
* * `+hh:mm:ss`
* * `-hh:mm:ss`
* * `+hhmmss`
* * `-hhmmss`
*
* Note that &plusmn; means either the plus or minus symbol.
*
* The ID of the returned offset will be normalized to one of the formats
* described by {@link getId}.
*
* The maximum supported range is from +18:00 to -18:00 inclusive.
*
* @param {string} offsetId the offset ID, not null
* @return {ZoneOffset} the zone-offset, not null
* @throws DateTimeException if the offset ID is invalid
*/
static of(offsetId) {
requireNonNull(offsetId, 'offsetId');
// "Z" is always in the cache
const offset = ID_CACHE[offsetId];
if (offset != null) {
return offset;
}
// parse - +h, +hh, +hhmm, +hh:mm, +hhmmss, +hh:mm:ss
let hours, minutes, seconds;
switch (offsetId.length) {
case 2:
offsetId = `${offsetId[0]}0${offsetId[1]}`; // fallthru
// eslint-disable-next-line no-fallthrough
case 3:
hours = ZoneOffset._parseNumber(offsetId, 1, false);
minutes = 0;
seconds = 0;
break;
case 5:
hours = ZoneOffset._parseNumber(offsetId, 1, false);
minutes = ZoneOffset._parseNumber(offsetId, 3, false);
seconds = 0;
break;
case 6:
hours = ZoneOffset._parseNumber(offsetId, 1, false);
minutes = ZoneOffset._parseNumber(offsetId, 4, true);
seconds = 0;
break;
case 7:
hours = ZoneOffset._parseNumber(offsetId, 1, false);
minutes = ZoneOffset._parseNumber(offsetId, 3, false);
seconds = ZoneOffset._parseNumber(offsetId, 5, false);
break;
case 9:
hours = ZoneOffset._parseNumber(offsetId, 1, false);
minutes = ZoneOffset._parseNumber(offsetId, 4, true);
seconds = ZoneOffset._parseNumber(offsetId, 7, true);
break;
default:
throw new DateTimeException(`Invalid ID for ZoneOffset, invalid format: ${offsetId}`);
}
const first = offsetId[0];
if (first !== '+' && first !== '-') {
throw new DateTimeException(`Invalid ID for ZoneOffset, plus/minus not found when expected: ${offsetId}`);
}
if (first === '-') {
return ZoneOffset.ofHoursMinutesSeconds(-hours, -minutes, -seconds);
} else {
return ZoneOffset.ofHoursMinutesSeconds(hours, minutes, seconds);
}
}
/**
* Parse a two digit zero-prefixed number.
*
* @param {string} offsetId - the offset ID, not null
* @param {number} pos - the position to parse, valid
* @param {boolean} precededByColon - should this number be prefixed by a precededByColon
* @return {number} the parsed number, from 0 to 99
*/
static _parseNumber(offsetId, pos, precededByColon) {
if (precededByColon && offsetId[pos - 1] !== ':') {
throw new DateTimeException(`Invalid ID for ZoneOffset, colon not found when expected: ${offsetId}`);
}
const ch1 = offsetId[pos];
const ch2 = offsetId[pos + 1];
if (ch1 < '0' || ch1 > '9' || ch2 < '0' || ch2 > '9') {
throw new DateTimeException(`Invalid ID for ZoneOffset, non numeric characters found: ${offsetId}`);
}
return (ch1.charCodeAt(0) - 48) * 10 + (ch2.charCodeAt(0) - 48);
}
/**
*
* @param {number} hours
* @returns {ZoneOffset}
*/
static ofHours(hours) {
return ZoneOffset.ofHoursMinutesSeconds(hours, 0, 0);
}
/**
*
* @param {number} hours
* @param {number} minutes
* @returns {ZoneOffset}
*/
static ofHoursMinutes(hours, minutes) {
return ZoneOffset.ofHoursMinutesSeconds(hours, minutes, 0);
}
/**
*
* @param {number} hours
* @param {number} minutes
* @param {number} seconds
* @returns {ZoneOffset}
*/
static ofHoursMinutesSeconds(hours, minutes, seconds) {
ZoneOffset._validate(hours, minutes, seconds);
const totalSeconds = hours * LocalTime.SECONDS_PER_HOUR + minutes * LocalTime.SECONDS_PER_MINUTE + seconds;
return ZoneOffset.ofTotalSeconds(totalSeconds);
}
/**
*
* @param {number} totalMinutes
* @returns {ZoneOffset}
*/
static ofTotalMinutes(totalMinutes) {
const totalSeconds = totalMinutes * LocalTime.SECONDS_PER_MINUTE;
return ZoneOffset.ofTotalSeconds(totalSeconds);
}
/**
*
* @param {number} totalSeconds
* @returns {ZoneOffset}
*/
static ofTotalSeconds(totalSeconds) {
if (totalSeconds % (15 * LocalTime.SECONDS_PER_MINUTE) === 0) {
const totalSecs = totalSeconds;
let result = SECONDS_CACHE[totalSecs];
if (result == null) {
result = new ZoneOffset(totalSeconds);
SECONDS_CACHE[totalSecs] = result;
ID_CACHE[result.id()] = result;
}
return result;
} else {
return new ZoneOffset(totalSeconds);
}
}
/**
* Gets the associated time-zone rules.
*
* The rules will always return this offset when queried.
* The implementation class is immutable, thread-safe and serializable.
*
* @return {ZoneRules} the rules, not null
*/
rules() {
return this._rules;
}
/**
* Gets the value of the specified field from this offset as an `int`.
*
* This queries this offset for the value for the specified field.
* The returned value will always be within the valid range of values for the field.
* If it is not possible to return the value, because the field is not supported
* or for some other reason, an exception is thrown.
*
* If the field is a {@link ChronoField} then the query is implemented here.
* The {@link OFFSET_SECONDS} field returns the value of the offset.
* All other {@link ChronoField} instances will throw a {@link DateTimeException}.
*
* If the field is not a {@link ChronoField}, then the result of this method
* is obtained by invoking {@link TemporalField.getFrom}
* passing `this` as the argument. Whether the value can be obtained,
* and what the value represents, is determined by the field.
*
* @param {TemporalField} field - the field to get, not null
* @return {number} the value for the field
* @throws DateTimeException if a value for the field cannot be obtained
* @throws ArithmeticException if numeric overflow occurs
*/
get(field) {
return this.getLong(field);
}
/**
* Gets the value of the specified field from this offset as a `long`.
*
* This queries this offset for the value for the specified field.
* If it is not possible to return the value, because the field is not supported
* or for some other reason, an exception is thrown.
*
* If the field is a {@link ChronoField} then the query is implemented here.
* The {@link OFFSET_SECONDS} field returns the value of the offset.
* All other {@link ChronoField} instances will throw a {@link DateTimeException}.
*
* If the field is not a {@link ChronoField}, then the result of this method
* is obtained by invoking {@link TemporalField.getFrom}
* passing `this` as the argument. Whether the value can be obtained,
* and what the value represents, is determined by the field.
*
* @param {TemporalField} field - the field to get, not null
* @return {number} the value for the field
* @throws DateTimeException if a value for the field cannot be obtained
* @throws ArithmeticException if numeric overflow occurs
*/
getLong(field) {
if (field === ChronoField.OFFSET_SECONDS) {
return this._totalSeconds;
} else if (field instanceof ChronoField) {
throw new DateTimeException(`Unsupported field: ${field}`);
}
return field.getFrom(this);
}
//-----------------------------------------------------------------------
/**
* Queries this offset using the specified query.
*
* This queries this offset using the specified query strategy object.
* The {@link TemporalQuery} object defines the logic to be used to
* obtain the result. Read the documentation of the query to understand
* what the result of this method will be.
*
* The result of this method is obtained by invoking the
* {@link TemporalQuery#queryFrom} method on the
* specified query passing `this` as the argument.
*
* @param {TemporalQuery} query - the query to invoke, not null
* @return {*} the query result, null may be returned (defined by the query)
* @throws DateTimeException if unable to query (defined by the query)
* @throws ArithmeticException if numeric overflow occurs (defined by the query)
*/
query(query) {
requireNonNull(query, 'query');
if (query === TemporalQueries.offset() || query === TemporalQueries.zone()) {
return this;
} else if (query === TemporalQueries.localDate() || query === TemporalQueries.localTime() ||
query === TemporalQueries.precision() || query === TemporalQueries.chronology() || query === TemporalQueries.zoneId()) {
return null;
}
return query.queryFrom(this);
}
/**
* Adjusts the specified temporal object to have the same offset as this object.
*
* This returns a temporal object of the same observable type as the input
* with the offset changed to be the same as this.
*
* The adjustment is equivalent to using {@link Temporal#with}
* passing {@link ChronoField#OFFSET_SECONDS} as the field.
*
* In most cases, it is clearer to reverse the calling pattern by using
* {@link Temporal#with}:
* <pre>
* // these two lines are equivalent, but the second approach is recommended
* temporal = thisOffset.adjustInto(temporal);
* temporal = temporal.with(thisOffset);
* </pre>
*
* This instance is immutable and unaffected by this method call.
*
* @param {Temporal} temporal - the target object to be adjusted, not null
* @return {Temporal} the adjusted object, not null
* @throws DateTimeException if unable to make the adjustment
* @throws ArithmeticException if numeric overflow occurs
*/
adjustInto(temporal) {
return temporal.with(ChronoField.OFFSET_SECONDS, this._totalSeconds);
}
/**
* Compares this offset to another offset in descending order.
*
* The offsets are compared in the order that they occur for the same time
* of day around the world. Thus, an offset of `+10:00` comes before an
* offset of `+09:00` and so on down to `-18:00`.
*
* The comparison is "consistent with equals", as defined by {@link Comparable}.
*
* @param {!ZoneOffset} other - the other date to compare to, not null
* @return {number} the comparator value, negative if less, positive if greater
* @throws NullPointerException if {@link other} is null
*/
compareTo(other) {
requireNonNull(other, 'other');
return other._totalSeconds - this._totalSeconds;
}
/**
* Checks if this offset is equal to another offset.
*
* The comparison is based on the amount of the offset in seconds.
* This is equivalent to a comparison by ID.
*
* @param {*} obj - the object to check, null returns false
* @return {boolean} true if this is equal to the other offset
*/
equals(obj) {
if (this === obj) {
return true;
}
if (obj instanceof ZoneOffset) {
return this._totalSeconds === obj._totalSeconds;
}
return false;
}
/**
* @return {number}
*/
hashCode(){
return this._totalSeconds;
}
/**
*
* @returns {string}
*/
toString(){
return this._id;
}
}
export function _init() {
ZoneOffset.MAX_SECONDS = 18 * LocalTime.SECONDS_PER_HOUR;
ZoneOffset.UTC = ZoneOffset.ofTotalSeconds(0);
ZoneOffset.MIN = ZoneOffset.ofTotalSeconds(-ZoneOffset.MAX_SECONDS);
ZoneOffset.MAX = ZoneOffset.ofTotalSeconds(ZoneOffset.MAX_SECONDS);
}

71
node_modules/@js-joda/core/src/ZoneRegion.js generated vendored Normal file
View File

@@ -0,0 +1,71 @@
/*
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
import { ZoneId } from './ZoneId';
import { ZoneRulesProvider } from './zone/ZoneRulesProvider';
/**
* A geographical region where the same time-zone rules apply.
*
* Time-zone information is categorized as a set of rules defining when and
* how the offset from UTC/Greenwich changes. These rules are accessed using
* identifiers based on geographical regions, such as countries or states.
* The most common region classification is the Time Zone Database (TZDB),
* which defines regions such as 'Europe/Paris' and 'Asia/Tokyo'.
*
* The region identifier, modeled by this class, is distinct from the
* underlying rules, modeled by {@link ZoneRules}.
* The rules are defined by governments and change frequently.
* By contrast, the region identifier is well-defined and long-lived.
* This separation also allows rules to be shared between regions if appropriate.
*
* ### Specification for implementors
*
* This class is immutable and thread-safe.
*/
export class ZoneRegion extends ZoneId {
/**
* @param {string} zoneId
* @return {ZoneId}
*/
static ofId(zoneId){
const rules = ZoneRulesProvider.getRules(zoneId);
return new ZoneRegion(zoneId, rules);
}
//-------------------------------------------------------------------------
/**
* Constructor.
*
* @param {string} id the time-zone ID, not null
* @param {ZoneRules} rules the rules, null for lazy lookup
* @private
*/
constructor(id, rules) {
super();
this._id = id;
this._rules = rules;
}
//-----------------------------------------------------------------------
/**
*
* @returns {string}
*/
id() {
return this._id;
}
/**
*
* @returns {ZoneRules}
*/
rules() {
return this._rules;
}
}

1964
node_modules/@js-joda/core/src/ZonedDateTime.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

68
node_modules/@js-joda/core/src/_init.js generated vendored Normal file
View File

@@ -0,0 +1,68 @@
/*
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
import { _init as ZoneOffsetInit } from './ZoneOffset';
import { _init as DayOfWeekInit } from './DayOfWeek';
import { _init as DurationInit } from './Duration';
import { _init as InstantInit } from './Instant';
import { _init as LocalDateInit } from './LocalDate';
import { _init as LocalTimeInit } from './LocalTime';
import { _init as LocalDateTimeInit } from './LocalDateTime';
import { _init as MonthInit } from './Month';
import { _init as MonthDayInit } from './MonthDay';
import { _init as OffsetDateTimeInit } from './OffsetDateTime';
import { _init as OffsetTimeInit } from './OffsetTime';
import { _init as PeriodInit } from './Period';
import { _init as YearInit } from './Year';
import { _init as YearConstantsInit } from './YearConstants';
import { _init as YearMonthInit } from './YearMonth';
import { _init as ZonedDateTimeInit } from './ZonedDateTime';
import { _init as IsoChronologyInit } from './chrono/IsoChronology';
import { _init as DateTimeFormatterInit } from './format/DateTimeFormatter';
import { _init as ChronoFieldInit } from './temporal/ChronoField';
import { _init as ChronoUnitInit } from './temporal/ChronoUnit';
import { _init as IsoFieldsInit } from './temporal/IsoFields';
import { _init as DateTimeFormatterBuilderInit } from './format/DateTimeFormatterBuilder';
import { _init as TemporalQueriesInit } from './temporal/TemporalQueriesFactory';
import { _init as ZoneIdInit } from './ZoneIdFactory';
let isInit = false;
function init() {
if (isInit) {
return;
}
isInit = true;
YearConstantsInit();
DurationInit();
ChronoUnitInit();
ChronoFieldInit();
LocalTimeInit();
IsoFieldsInit();
TemporalQueriesInit();
DayOfWeekInit();
InstantInit();
LocalDateInit();
LocalDateTimeInit();
YearInit();
MonthInit();
YearMonthInit();
MonthDayInit();
PeriodInit();
ZoneOffsetInit();
ZonedDateTimeInit();
ZoneIdInit();
IsoChronologyInit();
DateTimeFormatterInit();
DateTimeFormatterBuilderInit();
OffsetDateTimeInit();
OffsetTimeInit();
}
init();

60
node_modules/@js-joda/core/src/assert.js generated vendored Normal file
View File

@@ -0,0 +1,60 @@
/**
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
import { NullPointerException, IllegalArgumentException } from './errors';
/**
* @private
*
* @param assertion
* @param msg
* @param error
*/
export function assert(assertion, msg, error) {
if(!assertion){
if (error) {
throw new error(msg);
} else {
throw new Error(msg);
}
}
}
/**
* @private
*
* @param value
* @param parameterName
* @returns {*}
*/
export function requireNonNull(value, parameterName) {
if (value == null) {
throw new NullPointerException(`${parameterName} must not be null`);
}
return value;
}
/**
* @private
*
* @param value
* @param _class
* @param parameterName
* @returns {_class}
*/
export function requireInstance(value, _class, parameterName) {
if (!(value instanceof _class)) {
throw new IllegalArgumentException(`${parameterName} must be an instance of ${_class.name ? _class.name : _class}${value && value.constructor && value.constructor.name ? `, but is ${value.constructor.name}` : ''}`);
}
return value;
}
/**
* @private
*
* @param methodName
*/
export function abstractMethodFail(methodName){
throw new TypeError(`abstract method "${methodName}" is not implemented`);
}

View File

@@ -0,0 +1,230 @@
/*
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
import { requireNonNull, requireInstance } from '../assert';
import { ChronoField } from '../temporal/ChronoField';
import { ChronoUnit } from '../temporal/ChronoUnit';
import { DateTimeFormatter } from '../format/DateTimeFormatter';
import { TemporalQueries } from '../temporal/TemporalQueries';
import { Temporal } from '../temporal/Temporal';
import { LocalDate } from '../LocalDate';
/**
* A date without time-of-day or time-zone in an arbitrary chronology, intended
* for advanced globalization use cases.
*
* **Most applications should declare method signatures, fields and variables
* as {@link LocalDate}, not this interface.**
*
* A {@link ChronoLocalDate} is the abstract representation of a date where the
* {@link Chronology}, or calendar system, is pluggable.
* The date is defined in terms of fields expressed by {@link TemporalField},
* where most common implementations are defined in {@link ChronoField}.
* The chronology defines how the calendar system operates and the meaning of
* the standard fields.
*
* #### When to use this interface
*
* The design of the API encourages the use of {@link LocalDate} rather than this
* interface, even in the case where the application needs to deal with multiple
* calendar systems. The rationale for this is explored in the following documentation.
*
* The primary use case where this interface should be used is where the generic
* type parameter `C` is fully defined as a specific chronology.
* In that case, the assumptions of that chronology are known at development
* time and specified in the code.
*
* When the chronology is defined in the generic type parameter as ? or otherwise
* unknown at development time, the rest of the discussion below applies.
*
* To emphasize the point, declaring a method signature, field or variable as this
* interface type can initially seem like the sensible way to globalize an application,
* however it is usually the wrong approach.
* As such, it should be considered an application-wide architectural decision to choose
* to use this interface as opposed to {@link LocalDate}.
*
* #### Architectural issues to consider
*
* These are some of the points that must be considered before using this interface
* throughout an application.
*
* 1) Applications using this interface, as opposed to using just {@link LocalDate},
* face a significantly higher probability of bugs. This is because the calendar system
* in use is not known at development time. A key cause of bugs is where the developer
* applies assumptions from their day-to-day knowledge of the ISO calendar system
* to code that is intended to deal with any arbitrary calendar system.
* The section below outlines how those assumptions can cause problems
* The primary mechanism for reducing this increased risk of bugs is a strong code review process.
* This should also be considered a extra cost in maintenance for the lifetime of the code.
*
* 2) This interface does not enforce immutability of implementations.
* While the implementation notes indicate that all implementations must be immutable
* there is nothing in the code or type system to enforce this. Any method declared
* to accept a {@link ChronoLocalDate} could therefore be passed a poorly or
* maliciously written mutable implementation.
*
* 3) Applications using this interface must consider the impact of eras.
* {@link LocalDate} shields users from the concept of eras, by ensuring that `getYear()`
* returns the proleptic year. That decision ensures that developers can think of
* {@link LocalDate} instances as consisting of three fields - year, month-of-year and day-of-month.
* By contrast, users of this interface must think of dates as consisting of four fields -
* era, year-of-era, month-of-year and day-of-month. The extra era field is frequently
* forgotten, yet it is of vital importance to dates in an arbitrary calendar system.
* For example, in the Japanese calendar system, the era represents the reign of an Emperor.
* Whenever one reign ends and another starts, the year-of-era is reset to one.
*
* 4) The only agreed international standard for passing a date between two systems
* is the ISO-8601 standard which requires the ISO calendar system. Using this interface
* throughout the application will inevitably lead to the requirement to pass the date
* across a network or component boundary, requiring an application specific protocol or format.
*
* 5) Long term persistence, such as a database, will almost always only accept dates in the
* ISO-8601 calendar system (or the related Julian-Gregorian). Passing around dates in other
* calendar systems increases the complications of interacting with persistence.
*
* 6) Most of the time, passing a {@link ChronoLocalDate} throughout an application
* is unnecessary, as discussed in the last section below.
*
* #### False assumptions causing bugs in multi-calendar system code
*
* As indicated above, there are many issues to consider when try to use and manipulate a
* date in an arbitrary calendar system. These are some of the key issues.
*
* Code that queries the day-of-month and assumes that the value will never be more than
* 31 is invalid. Some calendar systems have more than 31 days in some months.
*
* Code that adds 12 months to a date and assumes that a year has been added is invalid.
* Some calendar systems have a different number of months, such as 13 in the Coptic or Ethiopic.
*
* Code that adds one month to a date and assumes that the month-of-year value will increase
* by one or wrap to the next year is invalid. Some calendar systems have a variable number
* of months in a year, such as the Hebrew.
*
* Code that adds one month, then adds a second one month and assumes that the day-of-month
* will remain close to its original value is invalid. Some calendar systems have a large difference
* between the length of the longest month and the length of the shortest month.
* For example, the Coptic or Ethiopic have 12 months of 30 days and 1 month of 5 days.
*
* Code that adds seven days and assumes that a week has been added is invalid.
* Some calendar systems have weeks of other than seven days, such as the French Revolutionary.
*
* Code that assumes that because the year of `date1` is greater than the year of `date2`
* then `date1` is after `date2` is invalid. This is invalid for all calendar systems
* when referring to the year-of-era, and especially untrue of the Japanese calendar system
* where the year-of-era restarts with the reign of every new Emperor.
*
* Code that treats month-of-year one and day-of-month one as the start of the year is invalid.
* Not all calendar systems start the year when the month value is one.
*
* In general, manipulating a date, and even querying a date, is wide open to bugs when the
* calendar system is unknown at development time. This is why it is essential that code using
* this interface is subjected to additional code reviews. It is also why an architectural
* decision to avoid this interface type is usually the correct one.
*
* #### Using LocalDate instead
*
* The primary alternative to using this interface throughout your application is as follows.
*
* * Declare all method signatures referring to dates in terms of {@link LocalDate}.
* * Either store the chronology (calendar system) in the user profile or lookup the chronology
* from the user locale.
* * Convert the ISO {@link LocalDate} to and from the user's preferred calendar system during
* printing and parsing.
*
* This approach treats the problem of globalized calendar systems as a localization issue
* and confines it to the UI layer. This approach is in keeping with other localization
* issues in the java platform.
*
* As discussed above, performing calculations on a date where the rules of the calendar system
* are pluggable requires skill and is not recommended.
* Fortunately, the need to perform calculations on a date in an arbitrary calendar system
* is extremely rare. For example, it is highly unlikely that the business rules of a library
* book rental scheme will allow rentals to be for one month, where meaning of the month
* is dependent on the user's preferred calendar system.
*
* A key use case for calculations on a date in an arbitrary calendar system is producing
* a month-by-month calendar for display and user interaction. Again, this is a UI issue,
* and use of this interface solely within a few methods of the UI layer may be justified.
*
* In any other part of the system, where a date must be manipulated in a calendar system
* other than ISO, the use case will generally specify the calendar system to use.
* For example, an application may need to calculate the next Islamic or Hebrew holiday
* which may require manipulating the date.
* This kind of use case can be handled as follows:
*
* * start from the ISO {@link LocalDate} being passed to the method
* * convert the date to the alternate calendar system, which for this use case is known
* rather than arbitrary
* * perform the calculation
* * convert back to {@link LocalDate}
*
* Developers writing low-level frameworks or libraries should also avoid this interface.
* Instead, one of the two general purpose access interfaces should be used.
* Use {@link TemporalAccessor} if read-only access is required, or use {@link Temporal}
* if read-write access is required.
*
* ### Specification for implementors
*
* This interface must be implemented with care to ensure other classes operate correctly.
* All implementations that can be instantiated must be final, immutable and thread-safe.
* Subclasses should be Serializable wherever possible.
*
* Additional calendar systems may be added to the system.
* See {@link Chronology} for more details.
*
* In JDK 8, this is an interface with default methods.
* Since there are no default methods in JDK 7, an abstract class is used.
*/
export class ChronoLocalDate extends Temporal {
isSupported(fieldOrUnit) {
if (fieldOrUnit instanceof ChronoField) {
return fieldOrUnit.isDateBased();
} else if (fieldOrUnit instanceof ChronoUnit) {
return fieldOrUnit.isDateBased();
}
return fieldOrUnit != null && fieldOrUnit.isSupportedBy(this);
}
query(query) {
if (query === TemporalQueries.chronology()) {
return this.chronology();
} else if (query === TemporalQueries.precision()) {
return ChronoUnit.DAYS;
} else if (query === TemporalQueries.localDate()) {
return LocalDate.ofEpochDay(this.toEpochDay());
} else if (query === TemporalQueries.localTime() || query === TemporalQueries.zone() ||
query === TemporalQueries.zoneId() || query === TemporalQueries.offset()) {
return null;
}
return super.query(query);
}
adjustInto(temporal) {
return temporal.with(ChronoField.EPOCH_DAY, this.toEpochDay());
}
/**
* Formats this date using the specified formatter.
*
* This date will be passed to the formatter to produce a string.
*
* The default implementation must behave as follows:
* <pre>
* return formatter.format(this);
* </pre>
*
* @param {DateTimeFormatter} formatter the formatter to use, not null
* @return {String} the formatted date string, not null
* @throws DateTimeException if an error occurs during printing
*/
format(formatter) {
requireNonNull(formatter, 'formatter');
requireInstance(formatter, DateTimeFormatter, 'formatter');
return formatter.format(this);
}
}

View File

@@ -0,0 +1,130 @@
/*
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
import { requireNonNull, requireInstance } from '../assert';
import { MathUtil } from '../MathUtil';
import { LocalDate } from '../LocalDate';
import { Instant } from '../Instant';
import { ZoneOffset } from '../ZoneOffset';
import { ChronoUnit } from '../temporal/ChronoUnit';
import { ChronoField } from '../temporal/ChronoField';
import { Temporal } from '../temporal/Temporal';
import { TemporalQueries } from '../temporal/TemporalQueries';
/**
* A date-time without a time-zone in an arbitrary chronology, intended
* for advanced globalization use cases.
*
* **Most applications should declare method signatures, fields and variables
* as {@link LocalDateTime}, not this interface.**
*
* A {@link ChronoLocalDateTime} is the abstract representation of a local date-time
* where the {@link Chronology}, or calendar system, is pluggable.
* The date-time is defined in terms of fields expressed by {@link TemporalField},
* where most common implementations are defined in {@link ChronoField}.
* The chronology defines how the calendar system operates and the meaning of
* the standard fields.
*
* #### When to use this interface
*
* The design of the API encourages the use of {@link LocalDateTime} rather than this
* interface, even in the case where the application needs to deal with multiple
* calendar systems. The rationale for this is explored in detail in {@link ChronoLocalDate}.
*
* Ensure that the discussion in {@link ChronoLocalDate} has been read and understood
* before using this interface.
*
* ### Specification for implementors
*
* This interface must be implemented with care to ensure other classes operate correctly.
* All implementations that can be instantiated must be final, immutable and thread-safe.
* Subclasses should be Serializable wherever possible.
*
* In JDK 8, this is an interface with default methods.
* Since there are no default methods in JDK 7, an abstract class is used.
*
* @param D the date type
*/
export class ChronoLocalDateTime extends Temporal {
/* <D extends ChronoLocalDate>
extends DefaultInterfaceTemporal
implements Temporal, TemporalAdjuster, Comparable<ChronoLocalDateTime<?>> */
//-----------------------------------------------------------------------
/**
* Gets the chronology of this date-time.
*
* The {@link Chronology} represents the calendar system in use.
* The era and other fields in {@link ChronoField} are defined by the chronology.
*
* @return the chronology, not null
*/
chronology() {
return this.toLocalDate().chronology();
}
/**
*
* @param {TemporalQuery} query
* @returns {*}
*/
query(query) {
if (query === TemporalQueries.chronology()) {
return this.chronology();
} else if (query === TemporalQueries.precision()) {
return ChronoUnit.NANOS;
} else if (query === TemporalQueries.localDate()) {
return LocalDate.ofEpochDay(this.toLocalDate().toEpochDay());
} else if (query === TemporalQueries.localTime()) {
return this.toLocalTime();
} else if (query === TemporalQueries.zone() || query === TemporalQueries.zoneId() || query === TemporalQueries.offset()) {
return null;
}
return super.query(query);
}
adjustInto(temporal) {
return temporal
.with(ChronoField.EPOCH_DAY, this.toLocalDate().toEpochDay())
.with(ChronoField.NANO_OF_DAY, this.toLocalTime().toNanoOfDay());
}
//-----------------------------------------------------------------------
/**
* Converts this date-time to an {@link Instant}.
*
* This combines this local date-time and the specified offset to form
* an {@link Instant}.
*
* @param {ZoneOffset} offset the offset to use for the conversion, not null
* @return {Instant} an {@link Instant} representing the same instant, not null
*/
toInstant(offset) {
requireInstance(offset, ZoneOffset, 'zoneId');
return Instant.ofEpochSecond(this.toEpochSecond(offset), this.toLocalTime().nano());
}
/**
* Converts this date-time to the number of seconds from the epoch
* of 1970-01-01T00:00:00Z.
*
* This combines this local date-time and the specified offset to calculate the
* epoch-second value, which is the number of elapsed seconds from 1970-01-01T00:00:00Z.
* Instants on the time-line after the epoch are positive, earlier are negative.
*
* @param {ZoneOffset} offset the offset to use for the conversion, not null
* @return {number} the number of seconds from the epoch of 1970-01-01T00:00:00Z
*/
toEpochSecond(offset) {
requireNonNull(offset, 'offset');
const epochDay = this.toLocalDate().toEpochDay();
let secs = epochDay * 86400 + this.toLocalTime().toSecondOfDay();
secs -= offset.totalSeconds();
return MathUtil.safeToInt(secs);
}
}

View File

@@ -0,0 +1,194 @@
/*
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
import { requireNonNull } from '../assert';
import { Instant } from '../Instant';
import { LocalDate } from '../LocalDate';
import { MathUtil } from '../MathUtil';
import { ChronoUnit } from '../temporal/ChronoUnit';
import { Temporal } from '../temporal/Temporal';
import { TemporalQueries } from '../temporal/TemporalQueries';
export class ChronoZonedDateTime extends Temporal {
query(query) {
if (query === TemporalQueries.zoneId() || query === TemporalQueries.zone()) {
return this.zone();
} else if (query === TemporalQueries.chronology()) {
return this.toLocalDate().chronology();
} else if (query === TemporalQueries.precision()) {
return ChronoUnit.NANOS;
} else if (query === TemporalQueries.offset()) {
return this.offset();
} else if (query === TemporalQueries.localDate()) {
return LocalDate.ofEpochDay(this.toLocalDate().toEpochDay());
} else if (query === TemporalQueries.localTime()) {
return this.toLocalTime();
}
return super.query(query);
}
/**
* Outputs this date-time as a string using the formatter.
*
* @param {DateTimeFormatter} formatter - the formatter to use, not null
* @return {string} the formatted date-time string, not null
* @throws DateTimeException if an error occurs during printing
*/
format(formatter) {
requireNonNull(formatter, 'formatter');
return formatter.format(this);
}
/**
* Converts this date-time to an {@link Instant}.
*
* This returns an {@link Instant} representing the same point on the
* time-line as this date-time. The calculation combines the
* local date-time (see {@link toLocalDateTime}) and
* offset (see {@link getOffset}).
*
* @return {Instant} an {@link Instant} representing the same instant, not null
*/
toInstant() {
return Instant.ofEpochSecond(this.toEpochSecond(), this.toLocalTime().nano());
}
/**
* Converts this date-time to the number of seconds from the epoch
* of 1970-01-01T00:00:00Z.
*
* This uses the local date-time (see {@link toLocalDateTime}) and
* offset (see {@link getOffset}) to calculate the epoch-second value,
* which is the number of elapsed seconds from 1970-01-01T00:00:00Z.
* Instants on the time-line after the epoch are positive, earlier are negative.
*
* @return {number} the number of seconds from the epoch of 1970-01-01T00:00:00Z
*/
toEpochSecond() {
const epochDay = this.toLocalDate().toEpochDay();
let secs = epochDay * 86400 + this.toLocalTime().toSecondOfDay();
secs -= this.offset().totalSeconds();
return secs;
}
/**
* Compares this date-time to another date-time, including the chronology.
*
* The comparison is based first on the instant, then on the local date-time,
* then on the zone ID, then on the chronology.
* It is "consistent with equals", as defined by {@link Comparable}.
*
* If all the date-time objects being compared are in the same chronology, then the
* additional chronology stage is not required.
*
* @param {ChronoZonedDateTime} other - the other date-time to compare to, not null
* @return {number} the comparator value, negative if less, positive if greater
*/
compareTo(other) {
requireNonNull(other, 'other');
let cmp = MathUtil.compareNumbers(this.toEpochSecond(), other.toEpochSecond());
if (cmp === 0) {
cmp = this.toLocalTime().nano() - other.toLocalTime().nano();
if (cmp === 0) {
cmp = this.toLocalDateTime().compareTo(other.toLocalDateTime());
if (cmp === 0) {
cmp = strcmp(this.zone().id(), other.zone().id());
// we only support iso for now
//if (cmp === 0) {
// cmp = toLocalDate().getChronology().compareTo(other.toLocalDate().getChronology());
//}
}
}
}
return cmp;
}
//-----------------------------------------------------------------------
/**
* Checks if the instant of this date-time is after that of the specified date-time.
*
* This method differs from the comparison in {@link compareTo} in that it
* only compares the instant of the date-time. This is equivalent to using
* `dateTime1.toInstant().isAfter(dateTime2.toInstant())`.
*
* @param {!ChronoZonedDateTime} other - the other date-time to compare to, not null
* @return {boolean} true if this is after the specified date-time
*/
isAfter(other) {
requireNonNull(other, 'other');
const thisEpochSec = this.toEpochSecond();
const otherEpochSec = other.toEpochSecond();
return thisEpochSec > otherEpochSec ||
(thisEpochSec === otherEpochSec && this.toLocalTime().nano() > other.toLocalTime().nano());
}
/**
* Checks if the instant of this date-time is before that of the specified date-time.
*
* This method differs from the comparison in {@link compareTo} in that it
* only compares the instant of the date-time. This is equivalent to using
* `dateTime1.toInstant().isBefore(dateTime2.toInstant())`.
*
* @param {!ChronoZonedDateTime} other - the other date-time to compare to, not null
* @return {boolean} true if this point is before the specified date-time
*/
isBefore(other) {
requireNonNull(other, 'other');
const thisEpochSec = this.toEpochSecond();
const otherEpochSec = other.toEpochSecond();
return thisEpochSec < otherEpochSec ||
(thisEpochSec === otherEpochSec && this.toLocalTime().nano() < other.toLocalTime().nano());
}
/**
* Checks if the instant of this date-time is equal to that of the specified date-time.
*
* This method differs from the comparison in {@link compareTo} and {@link equals}
* in that it only compares the instant of the date-time. This is equivalent to using
* `dateTime1.toInstant().equals(dateTime2.toInstant())`.
*
* @param {!ChronoZonedDateTime} other - the other date-time to compare to, not null
* @return {boolean} true if the instant equals the instant of the specified date-time
*/
isEqual(other) {
requireNonNull(other, 'other');
return this.toEpochSecond() === other.toEpochSecond() &&
this.toLocalTime().nano() === other.toLocalTime().nano();
}
//-----------------------------------------------------------------------
/**
* Checks if this date-time is equal to another date-time.
*
* The comparison is based on the offset date-time and the zone.
* To compare for the same instant on the time-line, use {@link compareTo}.
* Only objects of type {@link ChronoZoneDateTime} are compared, other types return false.
*
* @param {*} other the object to check, null returns false
* @return {boolean} true if this is equal to the other date-time
*/
equals(other) {
if (this === other) {
return true;
}
if (other instanceof ChronoZonedDateTime) {
return this.compareTo(other) === 0;
}
return false;
}
}
function strcmp(a, b){
if (a < b) {
return -1;
}
if (a > b) {
return 1;
}
return 0;
}

235
node_modules/@js-joda/core/src/chrono/IsoChronology.js generated vendored Normal file
View File

@@ -0,0 +1,235 @@
/**
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
import { Enum } from '../Enum';
import { requireNonNull } from '../assert';
import { DateTimeException } from '../errors';
import { MathUtil } from '../MathUtil';
import { DayOfWeek } from '../DayOfWeek';
import { LocalDate } from '../LocalDate';
import { Month } from '../Month';
import { Year } from '../Year';
import { ChronoField } from '../temporal/ChronoField';
import { ResolverStyle } from '../format/ResolverStyle';
import { TemporalAdjusters } from '../temporal/TemporalAdjusters';
export class IsoChronology extends Enum{
/**
* Checks if the year is a leap year, according to the ISO proleptic
* calendar system rules.
*
* This method applies the current rules for leap years across the whole time-line.
* In general, a year is a leap year if it is divisible by four without
* remainder. However, years divisible by 100, are not leap years, with
* the exception of years divisible by 400 which are.
*
* For example, 1904 is a leap year it is divisible by 4.
* 1900 was not a leap year as it is divisible by 100, however 2000 was a
* leap year as it is divisible by 400.
*
* The calculation is proleptic - applying the same rules into the far future and far past.
* This is historically inaccurate, but is correct for the ISO-8601 standard.
*
* @param {number} prolepticYear - the ISO proleptic year to check
* @return {boolean} true if the year is leap, false otherwise
*/
static isLeapYear(prolepticYear) {
return ((prolepticYear & 3) === 0) && ((prolepticYear % 100) !== 0 || (prolepticYear % 400) === 0);
}
/**
* Updates the map of field-values during resolution.
*
* @param {EnumMap} fieldValues the fieldValues map to update, not null
* @param {ChronoField} field the field to update, not null
* @param {number} value the value to update, not null
* @throws DateTimeException if a conflict occurs
*/
_updateResolveMap(fieldValues, field, value) {
// TODO: this function is in Chronology in threetenbp, maybe needs to be moved?
requireNonNull(fieldValues, 'fieldValues');
requireNonNull(field, 'field');
const current = fieldValues.get(field);
if (current != null && current !== value) {
throw new DateTimeException(`Invalid state, field: ${field} ${current} conflicts with ${field} ${value}`);
}
fieldValues.put(field, value);
}
resolveDate(fieldValues, resolverStyle) {
if (fieldValues.containsKey(ChronoField.EPOCH_DAY)) {
return LocalDate.ofEpochDay(fieldValues.remove(ChronoField.EPOCH_DAY));
}
// normalize fields
const prolepticMonth = fieldValues.remove(ChronoField.PROLEPTIC_MONTH);
if (prolepticMonth != null) {
if (resolverStyle !== ResolverStyle.LENIENT) {
ChronoField.PROLEPTIC_MONTH.checkValidValue(prolepticMonth);
}
this._updateResolveMap(fieldValues, ChronoField.MONTH_OF_YEAR, MathUtil.floorMod(prolepticMonth, 12) + 1);
this._updateResolveMap(fieldValues, ChronoField.YEAR, MathUtil.floorDiv(prolepticMonth, 12));
}
// eras
const yoeLong = fieldValues.remove(ChronoField.YEAR_OF_ERA);
if (yoeLong != null) {
if (resolverStyle !== ResolverStyle.LENIENT) {
ChronoField.YEAR_OF_ERA.checkValidValue(yoeLong);
}
const era = fieldValues.remove(ChronoField.ERA);
if (era == null) {
const year = fieldValues.get(ChronoField.YEAR);
if (resolverStyle === ResolverStyle.STRICT) {
// do not invent era if strict, but do cross-check with year
if (year != null) {
this._updateResolveMap(fieldValues, ChronoField.YEAR, (year > 0 ? yoeLong: MathUtil.safeSubtract(1, yoeLong)));
} else {
// reinstate the field removed earlier, no cross-check issues
fieldValues.put(ChronoField.YEAR_OF_ERA, yoeLong);
}
} else {
// invent era
this._updateResolveMap(fieldValues, ChronoField.YEAR, (year == null || year > 0 ? yoeLong: MathUtil.safeSubtract(1, yoeLong)));
}
} else if (era === 1) {
this._updateResolveMap(fieldValues, ChronoField.YEAR, yoeLong);
} else if (era === 0) {
this._updateResolveMap(fieldValues, ChronoField.YEAR, MathUtil.safeSubtract(1, yoeLong));
} else {
throw new DateTimeException(`Invalid value for era: ${era}`);
}
} else if (fieldValues.containsKey(ChronoField.ERA)) {
ChronoField.ERA.checkValidValue(fieldValues.get(ChronoField.ERA)); // always validated
}
// build date
if (fieldValues.containsKey(ChronoField.YEAR)) {
if (fieldValues.containsKey(ChronoField.MONTH_OF_YEAR)) {
if (fieldValues.containsKey(ChronoField.DAY_OF_MONTH)) {
const y = ChronoField.YEAR.checkValidIntValue(fieldValues.remove(ChronoField.YEAR));
const moy = fieldValues.remove(ChronoField.MONTH_OF_YEAR);
let dom = fieldValues.remove(ChronoField.DAY_OF_MONTH);
if (resolverStyle === ResolverStyle.LENIENT) {
const months = moy - 1;
const days = dom - 1;
return LocalDate.of(y, 1, 1).plusMonths(months).plusDays(days);
} else if (resolverStyle === ResolverStyle.SMART){
ChronoField.DAY_OF_MONTH.checkValidValue(dom);
if (moy === 4 || moy === 6 || moy === 9 || moy === 11) {
dom = Math.min(dom, 30);
} else if (moy === 2) {
dom = Math.min(dom, Month.FEBRUARY.length(Year.isLeap(y)));
}
return LocalDate.of(y, moy, dom);
} else {
return LocalDate.of(y, moy, dom);
}
}
/*
if (fieldValues.containsKey(ALIGNED_WEEK_OF_MONTH)) {
if (fieldValues.containsKey(ALIGNED_DAY_OF_WEEK_IN_MONTH)) {
int y = ChronoField.YEAR.checkValidIntValue(fieldValues.remove(ChronoField.YEAR));
if (resolverStyle == ResolverStyle.LENIENT) {
long months = Jdk8Methods.safeSubtract(fieldValues.remove(ChronoField.MONTH_OF_YEAR), 1);
long weeks = Jdk8Methods.safeSubtract(fieldValues.remove(ALIGNED_WEEK_OF_MONTH), 1);
long days = Jdk8Methods.safeSubtract(fieldValues.remove(ALIGNED_DAY_OF_WEEK_IN_MONTH), 1);
return LocalDate.of(y, 1, 1).plusMonths(months).plusWeeks(weeks).plusDays(days);
}
int moy = ChronoField.MONTH_OF_YEAR.checkValidIntValue(fieldValues.remove(ChronoField.MONTH_OF_YEAR));
int aw = ALIGNED_WEEK_OF_MONTH.checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_MONTH));
int ad = ALIGNED_DAY_OF_WEEK_IN_MONTH.checkValidIntValue(fieldValues.remove(ALIGNED_DAY_OF_WEEK_IN_MONTH));
LocalDate date = LocalDate.of(y, moy, 1).plusDays((aw - 1) * 7 + (ad - 1));
if (resolverStyle == ResolverStyle.STRICT && date.get(ChronoField.MONTH_OF_YEAR) != moy) {
throw new DateTimeException("Strict mode rejected date parsed to a different month");
}
return date;
}
if (fieldValues.containsKey(DAY_OF_WEEK)) {
int y = ChronoField.YEAR.checkValidIntValue(fieldValues.remove(ChronoField.YEAR));
if (resolverStyle == ResolverStyle.LENIENT) {
long months = Jdk8Methods.safeSubtract(fieldValues.remove(ChronoField.MONTH_OF_YEAR), 1);
long weeks = Jdk8Methods.safeSubtract(fieldValues.remove(ALIGNED_WEEK_OF_MONTH), 1);
long days = Jdk8Methods.safeSubtract(fieldValues.remove(DAY_OF_WEEK), 1);
return LocalDate.of(y, 1, 1).plusMonths(months).plusWeeks(weeks).plusDays(days);
}
int moy = ChronoField.MONTH_OF_YEAR.checkValidIntValue(fieldValues.remove(ChronoField.MONTH_OF_YEAR));
int aw = ALIGNED_WEEK_OF_MONTH.checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_MONTH));
int dow = DAY_OF_WEEK.checkValidIntValue(fieldValues.remove(DAY_OF_WEEK));
LocalDate date = LocalDate.of(y, moy, 1).plusWeeks(aw - 1).with(nextOrSame(DayOfWeek.of(dow)));
if (resolverStyle == ResolverStyle.STRICT && date.get(ChronoField.MONTH_OF_YEAR) != moy) {
throw new DateTimeException("Strict mode rejected date parsed to a different month");
}
return date;
}
}
*/
}
if (fieldValues.containsKey(ChronoField.DAY_OF_YEAR)) {
const y = ChronoField.YEAR.checkValidIntValue(fieldValues.remove(ChronoField.YEAR));
if (resolverStyle === ResolverStyle.LENIENT) {
const days = MathUtil.safeSubtract(fieldValues.remove(ChronoField.DAY_OF_YEAR), 1);
return LocalDate.ofYearDay(y, 1).plusDays(days);
}
const doy = ChronoField.DAY_OF_YEAR.checkValidIntValue(fieldValues.remove(ChronoField.DAY_OF_YEAR));
return LocalDate.ofYearDay(y, doy);
}
if (fieldValues.containsKey(ChronoField.ALIGNED_WEEK_OF_YEAR)) {
if (fieldValues.containsKey(ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR)) {
const y = ChronoField.YEAR.checkValidIntValue(fieldValues.remove(ChronoField.YEAR));
if (resolverStyle === ResolverStyle.LENIENT) {
const weeks = MathUtil.safeSubtract(fieldValues.remove(ChronoField.ALIGNED_WEEK_OF_YEAR), 1);
const days = MathUtil.safeSubtract(fieldValues.remove(ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR), 1);
return LocalDate.of(y, 1, 1).plusWeeks(weeks).plusDays(days);
}
const aw = ChronoField.ALIGNED_WEEK_OF_YEAR.checkValidIntValue(fieldValues.remove(ChronoField.ALIGNED_WEEK_OF_YEAR));
const ad = ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR.checkValidIntValue(fieldValues.remove(ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR));
const date = LocalDate.of(y, 1, 1).plusDays((aw - 1) * 7 + (ad - 1));
if (resolverStyle === ResolverStyle.STRICT && date.get(ChronoField.YEAR) !== y) {
throw new DateTimeException('Strict mode rejected date parsed to a different year');
}
return date;
}
if (fieldValues.containsKey(ChronoField.DAY_OF_WEEK)) {
const y = ChronoField.YEAR.checkValidIntValue(fieldValues.remove(ChronoField.YEAR));
if (resolverStyle === ResolverStyle.LENIENT) {
const weeks = MathUtil.safeSubtract(fieldValues.remove(ChronoField.ALIGNED_WEEK_OF_YEAR), 1);
const days = MathUtil.safeSubtract(fieldValues.remove(ChronoField.DAY_OF_WEEK), 1);
return LocalDate.of(y, 1, 1).plusWeeks(weeks).plusDays(days);
}
const aw = ChronoField.ALIGNED_WEEK_OF_YEAR.checkValidIntValue(fieldValues.remove(ChronoField.ALIGNED_WEEK_OF_YEAR));
const dow = ChronoField.DAY_OF_WEEK.checkValidIntValue(fieldValues.remove(ChronoField.DAY_OF_WEEK));
const date = LocalDate.of(y, 1, 1).plusWeeks(aw - 1).with(TemporalAdjusters.nextOrSame(DayOfWeek.of(dow)));
if (resolverStyle === ResolverStyle.STRICT && date.get(ChronoField.YEAR) !== y) {
throw new DateTimeException('Strict mode rejected date parsed to a different month');
}
return date;
}
}
}
return null;
}
/**
* Obtains an ISO local date from another date-time object.
* <p>
* This is equivalent to {@link LocalDate#from(TemporalAccessor)}.
*
* @param temporal the date-time object to convert, not null
* @return the ISO local date, not null
* @throws DateTimeException if unable to create the date
*/
date(temporal) {
return LocalDate.from(temporal);
}
}
export function _init() {
IsoChronology.INSTANCE = new IsoChronology('IsoChronology');
}

87
node_modules/@js-joda/core/src/convert.js generated vendored Normal file
View File

@@ -0,0 +1,87 @@
/*
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
import { IllegalArgumentException } from './errors';
import { LocalDate } from './LocalDate';
import { LocalDateTime } from './LocalDateTime';
import { ZonedDateTime } from './ZonedDateTime';
import { ZoneId } from './ZoneId';
import { Instant } from './Instant';
class ToNativeJsConverter {
/**
* @param {!(LocalDate|LocalDateTime|ZonedDateTime|Instant)} temporal - a joda temporal instance
* @param {ZoneId} [zone] - the zone of the temporal,
* the default value for LocalDate and LocalDateTime is ZoneId.systemDefault().
*/
constructor(temporal, zone){
let zonedDateTime;
if(temporal instanceof Instant) {
this.instant = temporal;
return;
} else if(temporal instanceof LocalDate) {
zone = zone == null ? ZoneId.systemDefault() : zone;
zonedDateTime = temporal.atStartOfDay(zone);
} else if (temporal instanceof LocalDateTime) {
zone = zone == null ? ZoneId.systemDefault() : zone;
zonedDateTime = temporal.atZone(zone);
} else if (temporal instanceof ZonedDateTime) {
if (zone == null) {
zonedDateTime = temporal;
} else {
zonedDateTime = temporal.withZoneSameInstant(zone);
}
} else {
throw new IllegalArgumentException(`unsupported instance for convert operation:${temporal}`);
}
this.instant = zonedDateTime.toInstant();
}
/**
*
* @returns {Date}
*/
toDate() {
return new Date(this.instant.toEpochMilli());
}
/**
*
* @returns {number}
*/
toEpochMilli() {
return this.instant.toEpochMilli();
}
}
/**
* converts a LocalDate, LocalDateTime or ZonedDateTime to a native Javascript Date.
*
* In a first step the temporal is converted to an Instant by adding implicit values.
*
* A LocalDate is implicit set to a LocalDateTime at start of day.
* A LocalDateTime is implicit set to a ZonedDateTime with
* the passed zone or if null, with the system default time zone.
* A ZonedDateTime is converted to an Instant, if a zone is specified the zonedDateTime is adjusted to this
* zone, keeping the same Instant.
*
* In a second step the instant is converted to a native Javascript Date
*
* default zone for LocalDate and LocalDateTime is ZoneId.systemDefault().
*
* @example
* convert(localDate).toDate() // returns a javascript Date
* convert(localDate).toEpochMilli() // returns the epochMillis
*
* @param {!(LocalDate|LocalDateTime|ZonedDateTime)} temporal - a joda temporal instance
* @param {ZoneId} [zone] - the zone of the temporal
* @returns {ToNativeJsConverter}
*/
export function convert(temporal, zone){
return new ToNativeJsConverter(temporal, zone);
}

54
node_modules/@js-joda/core/src/errors.js generated vendored Normal file
View File

@@ -0,0 +1,54 @@
/**
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
function createErrorType(name, init, superErrorClass = Error) {
function JsJodaException(message) {
if (!Error.captureStackTrace) {
this.stack = (new Error()).stack;
} else {
Error.captureStackTrace(this, this.constructor);
}
this.message = message;
init && init.apply(this, arguments);
this.toString = function () {
return `${this.name}: ${this.message}`;
};
}
JsJodaException.prototype = Object.create(superErrorClass.prototype);
JsJodaException.prototype.name = name;
JsJodaException.prototype.constructor = JsJodaException;
return JsJodaException;
}
export const DateTimeException = createErrorType('DateTimeException', messageWithCause);
export const DateTimeParseException = createErrorType('DateTimeParseException', messageForDateTimeParseException);
export const UnsupportedTemporalTypeException = createErrorType('UnsupportedTemporalTypeException', null, DateTimeException);
export const ArithmeticException = createErrorType('ArithmeticException');
export const IllegalArgumentException = createErrorType('IllegalArgumentException');
export const IllegalStateException = createErrorType('IllegalStateException');
export const NullPointerException = createErrorType('NullPointerException');
function messageWithCause(message, cause = null) {
let msg = message || this.name;
if (cause !== null && cause instanceof Error) {
msg += `\n-------\nCaused by: ${cause.stack}\n-------\n`;
}
this.message = msg;
}
function messageForDateTimeParseException(message, text = '', index = 0, cause = null) {
let msg = message || this.name;
msg += `: ${text}, at index: ${index}`;
if (cause !== null && cause instanceof Error) {
msg += `\n-------\nCaused by: ${cause.stack}\n-------\n`;
}
this.message = msg;
this.parsedString = () => {
return text;
};
this.errorIndex = () => {
return index;
};
}

View File

@@ -0,0 +1,535 @@
/*
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
import { requireNonNull } from '../assert';
import { DateTimeException } from '../errors';
import { MathUtil } from '../MathUtil';
import { EnumMap } from './EnumMap';
import { ResolverStyle } from './ResolverStyle';
import { IsoChronology } from '../chrono/IsoChronology';
import { ChronoLocalDate } from '../chrono/ChronoLocalDate';
import { ChronoField } from '../temporal/ChronoField';
import { TemporalAccessor } from '../temporal/TemporalAccessor';
import { TemporalQueries } from '../temporal/TemporalQueries';
import { LocalTime } from '../LocalTime';
import { LocalDate } from '../LocalDate';
import { Period } from '../Period';
import { ZoneOffset } from '../ZoneOffset';
/**
* Builder that can holds date and time fields and related date and time objects.
*
* The builder is used to hold onto different elements of date and time.
* It is designed as two separate maps:
*
* * from {@link TemporalField} to `long` value, where the value may be
* outside the valid range for the field
* * from {@link Class} to {@link TemporalAccessor}, holding larger scale objects
* like {@link LocalDateTime}.
*
* @private
*/
export class DateTimeBuilder extends TemporalAccessor {
/**
* Creates a new instance of the builder with a single field-value.
*
* This is equivalent to using {@link addFieldValue} on an empty builder.
*
* @param {TemporalField} field - the field to add, not null
* @param {number} value - the value to add, not null
* @return {DateTimeBuilder}
*/
static create(field, value) {
const dtb = new DateTimeBuilder();
dtb._addFieldValue(field, value);
return dtb;
}
constructor(){
super();
/**
* The map of other fields.
*/
this.fieldValues = new EnumMap();
/**
* The chronology.
*/
this.chrono = null;
/**
* The zone.
*/
this.zone = null;
/**
* The date.
*/
this.date = null;
/**
* The time.
*/
this.time = null;
/**
* The leap second flag.
*/
this.leapSecond = false;
/**
* The excess days.
*/
this.excessDays = null;
}
/**
*
* @param {TemporalField} field
* @return {Number} field value
*/
getFieldValue0(field) {
return this.fieldValues.get(field);
}
/**
* Adds a field-value pair to the builder.
*
* This adds a field to the builder.
* If the field is not already present, then the field-value pair is added to the map.
* If the field is already present and it has the same value as that specified, no action occurs.
* If the field is already present and it has a different value to that specified, then
* an exception is thrown.
*
* @param {TemporalField} field - the field to add, not null
* @param {Number} value - the value to add, not null
* @return {DateTimeBuilder}, this for method chaining
* @throws DateTimeException if the field is already present with a different value
*/
_addFieldValue(field, value) {
requireNonNull(field, 'field');
const old = this.getFieldValue0(field); // check first for better error message
if (old != null && old !== value) {
throw new DateTimeException(`Conflict found: ${field} ${old} differs from ${field} ${value}: ${this}`);
}
return this._putFieldValue0(field, value);
}
/**
* @param {TemporalField} field
* @param {Number} value
* @return {DateTimeBuilder}, this for method chaining
*/
_putFieldValue0(field, value) {
this.fieldValues.put(field, value);
return this;
}
/**
* Resolves the builder, evaluating the date and time.
*
* This examines the contents of the build.er and resolves it to produce the best
* available date and time, throwing an exception if a problem occurs.
* Calling this method changes the state of the builder.
*
* @param {ResolverStyle} resolverStyle - how to resolve
* @param {TemporalField[]} resolverFields
* @return {DateTimeBuilder} this, for method chaining
*/
resolve(resolverStyle, resolverFields) {
if (resolverFields != null) {
this.fieldValues.retainAll(resolverFields);
}
// handle standard fields
// this._mergeInstantFields();
this._mergeDate(resolverStyle);
this._mergeTime(resolverStyle);
//if (resolveFields(resolverStyle)) {
// mergeInstantFields();
// mergeDate(resolverStyle);
// mergeTime(resolverStyle);
//}
this._resolveTimeInferZeroes(resolverStyle);
//this._crossCheck();
if (this.excessDays != null && this.excessDays.isZero() === false && this.date != null && this.time != null) {
this.date = this.date.plus(this.excessDays);
this.excessDays = Period.ZERO;
}
//resolveFractional();
this._resolveInstant();
return this;
}
/**
*
* @param {ResolverStyle} resolverStyle
* @private
*/
_mergeDate(resolverStyle) {
//if (this.chrono instanceof IsoChronology) {
this._checkDate(IsoChronology.INSTANCE.resolveDate(this.fieldValues, resolverStyle));
//} else {
// if (this.fieldValues.containsKey(ChronoField.EPOCH_DAY)) {
// this._checkDate(LocalDate.ofEpochDay(this.fieldValues.remove(ChronoField.EPOCH_DAY)));
// return;
// }
//}
}
/**
*
* @param {LocalDate} date
* @private
*/
_checkDate(date) {
if (date != null) {
this._addObject(date);
for (const fieldName in this.fieldValues.keySet()) {
const field = ChronoField.byName(fieldName);
if (field) {
if (this.fieldValues.get(field) !== undefined) { // undefined if "removed" in EnumMap
if (field.isDateBased()) {
let val1;
try {
val1 = date.getLong(field);
} catch (ex) {
if (ex instanceof DateTimeException) {
continue;
} else {
throw ex;
}
}
const val2 = this.fieldValues.get(field);
if (val1 !== val2) {
throw new DateTimeException(`Conflict found: Field ${field} ${val1} differs from ${field} ${val2} derived from ${date}`);
}
}
}
}
}
}
}
/**
*
* @param {ResolverStyle} resolverStyle
* @private
*/
_mergeTime(resolverStyle) {
if (this.fieldValues.containsKey(ChronoField.CLOCK_HOUR_OF_DAY)) {
const ch = this.fieldValues.remove(ChronoField.CLOCK_HOUR_OF_DAY);
if (resolverStyle !== ResolverStyle.LENIENT) {
if (resolverStyle === ResolverStyle.SMART && ch === 0) {
// ok
} else {
ChronoField.CLOCK_HOUR_OF_DAY.checkValidValue(ch);
}
}
this._addFieldValue(ChronoField.HOUR_OF_DAY, ch === 24 ? 0 : ch);
}
if (this.fieldValues.containsKey(ChronoField.CLOCK_HOUR_OF_AMPM)) {
const ch = this.fieldValues.remove(ChronoField.CLOCK_HOUR_OF_AMPM);
if (resolverStyle !== ResolverStyle.LENIENT) {
if (resolverStyle === ResolverStyle.SMART && ch === 0) {
// ok
} else {
ChronoField.CLOCK_HOUR_OF_AMPM.checkValidValue(ch);
}
}
this._addFieldValue(ChronoField.HOUR_OF_AMPM, ch === 12 ? 0 : ch);
}
if (resolverStyle !== ResolverStyle.LENIENT) {
if (this.fieldValues.containsKey(ChronoField.AMPM_OF_DAY)) {
ChronoField.AMPM_OF_DAY.checkValidValue(this.fieldValues.get(ChronoField.AMPM_OF_DAY));
}
if (this.fieldValues.containsKey(ChronoField.HOUR_OF_AMPM)) {
ChronoField.HOUR_OF_AMPM.checkValidValue(this.fieldValues.get(ChronoField.HOUR_OF_AMPM));
}
}
if (this.fieldValues.containsKey(ChronoField.AMPM_OF_DAY) && this.fieldValues.containsKey(ChronoField.HOUR_OF_AMPM)) {
const ap = this.fieldValues.remove(ChronoField.AMPM_OF_DAY);
const hap = this.fieldValues.remove(ChronoField.HOUR_OF_AMPM);
this._addFieldValue(ChronoField.HOUR_OF_DAY, ap * 12 + hap);
}
// if (timeFields.containsKey(HOUR_OF_DAY) && timeFields.containsKey(MINUTE_OF_HOUR)) {
// const hod = timeFields.remove(HOUR_OF_DAY);
// const moh = timeFields.remove(MINUTE_OF_HOUR);
// this._addFieldValue(MINUTE_OF_DAY, hod * 60 + moh);
// }
// if (timeFields.containsKey(MINUTE_OF_DAY) && timeFields.containsKey(SECOND_OF_MINUTE)) {
// const mod = timeFields.remove(MINUTE_OF_DAY);
// const som = timeFields.remove(SECOND_OF_MINUTE);
// this._addFieldValue(SECOND_OF_DAY, mod * 60 + som);
// }
if (this.fieldValues.containsKey(ChronoField.NANO_OF_DAY)) {
const nod = this.fieldValues.remove(ChronoField.NANO_OF_DAY);
if (resolverStyle !== ResolverStyle.LENIENT) {
ChronoField.NANO_OF_DAY.checkValidValue(nod);
}
this._addFieldValue(ChronoField.SECOND_OF_DAY, MathUtil.intDiv(nod, 1000000000));
this._addFieldValue(ChronoField.NANO_OF_SECOND, MathUtil.intMod(nod, 1000000000));
}
if (this.fieldValues.containsKey(ChronoField.MICRO_OF_DAY)) {
const cod = this.fieldValues.remove(ChronoField.MICRO_OF_DAY);
if (resolverStyle !== ResolverStyle.LENIENT) {
ChronoField.MICRO_OF_DAY.checkValidValue(cod);
}
this._addFieldValue(ChronoField.SECOND_OF_DAY, MathUtil.intDiv(cod, 1000000));
this._addFieldValue(ChronoField.MICRO_OF_SECOND, MathUtil.intMod(cod, 1000000));
}
if (this.fieldValues.containsKey(ChronoField.MILLI_OF_DAY)) {
const lod = this.fieldValues.remove(ChronoField.MILLI_OF_DAY);
if (resolverStyle !== ResolverStyle.LENIENT) {
ChronoField.MILLI_OF_DAY.checkValidValue(lod);
}
this._addFieldValue(ChronoField.SECOND_OF_DAY, MathUtil.intDiv(lod, 1000));
this._addFieldValue(ChronoField.MILLI_OF_SECOND, MathUtil.intMod(lod, 1000));
}
if (this.fieldValues.containsKey(ChronoField.SECOND_OF_DAY)) {
const sod = this.fieldValues.remove(ChronoField.SECOND_OF_DAY);
if (resolverStyle !== ResolverStyle.LENIENT) {
ChronoField.SECOND_OF_DAY.checkValidValue(sod);
}
this._addFieldValue(ChronoField.HOUR_OF_DAY, MathUtil.intDiv(sod, 3600));
this._addFieldValue(ChronoField.MINUTE_OF_HOUR, MathUtil.intMod(MathUtil.intDiv(sod, 60), 60));
this._addFieldValue(ChronoField.SECOND_OF_MINUTE, MathUtil.intMod(sod, 60));
}
if (this.fieldValues.containsKey(ChronoField.MINUTE_OF_DAY)) {
const mod = this.fieldValues.remove(ChronoField.MINUTE_OF_DAY);
if (resolverStyle !== ResolverStyle.LENIENT) {
ChronoField.MINUTE_OF_DAY.checkValidValue(mod);
}
this._addFieldValue(ChronoField.HOUR_OF_DAY, MathUtil.intDiv(mod, 60));
this._addFieldValue(ChronoField.MINUTE_OF_HOUR, MathUtil.intMod(mod, 60));
}
// const sod = MathUtil.intDiv(nod, 1000000000L);
// this._addFieldValue(HOUR_OF_DAY, MathUtil.intDiv(sod, 3600));
// this._addFieldValue(MINUTE_OF_HOUR, MathUtil.intMod(MathUtil.intDiv(sod, 60), 60));
// this._addFieldValue(SECOND_OF_MINUTE, MathUtil.intMod(sod, 60));
// this._addFieldValue(NANO_OF_SECOND, MathUtil.intMod(nod, 1000000000L));
if (resolverStyle !== ResolverStyle.LENIENT) {
if (this.fieldValues.containsKey(ChronoField.MILLI_OF_SECOND)) {
ChronoField.MILLI_OF_SECOND.checkValidValue(this.fieldValues.get(ChronoField.MILLI_OF_SECOND));
}
if (this.fieldValues.containsKey(ChronoField.MICRO_OF_SECOND)) {
ChronoField.MICRO_OF_SECOND.checkValidValue(this.fieldValues.get(ChronoField.MICRO_OF_SECOND));
}
}
if (this.fieldValues.containsKey(ChronoField.MILLI_OF_SECOND) && this.fieldValues.containsKey(ChronoField.MICRO_OF_SECOND)) {
const los = this.fieldValues.remove(ChronoField.MILLI_OF_SECOND);
const cos = this.fieldValues.get(ChronoField.MICRO_OF_SECOND);
this._putFieldValue0(ChronoField.MICRO_OF_SECOND, los * 1000 + (MathUtil.intMod(cos, 1000)));
}
if (this.fieldValues.containsKey(ChronoField.MICRO_OF_SECOND) && this.fieldValues.containsKey(ChronoField.NANO_OF_SECOND)) {
const nos = this.fieldValues.get(ChronoField.NANO_OF_SECOND);
this._putFieldValue0(ChronoField.MICRO_OF_SECOND, MathUtil.intDiv(nos, 1000));
this.fieldValues.remove(ChronoField.MICRO_OF_SECOND);
}
if (this.fieldValues.containsKey(ChronoField.MILLI_OF_SECOND) && this.fieldValues.containsKey(ChronoField.NANO_OF_SECOND)) {
const nos = this.fieldValues.get(ChronoField.NANO_OF_SECOND);
this._putFieldValue0(ChronoField.MILLI_OF_SECOND, MathUtil.intDiv(nos, 1000000));
this.fieldValues.remove(ChronoField.MILLI_OF_SECOND);
}
if (this.fieldValues.containsKey(ChronoField.MICRO_OF_SECOND)) {
const cos = this.fieldValues.remove(ChronoField.MICRO_OF_SECOND);
this._putFieldValue0(ChronoField.NANO_OF_SECOND, cos * 1000);
} else if (this.fieldValues.containsKey(ChronoField.MILLI_OF_SECOND)) {
const los = this.fieldValues.remove(ChronoField.MILLI_OF_SECOND);
this._putFieldValue0(ChronoField.NANO_OF_SECOND, los * 1000000);
}
}
/**
*
* @param {ResolverStyle} resolverStyle
* @private
*/
_resolveTimeInferZeroes(resolverStyle) {
let hod = this.fieldValues.get(ChronoField.HOUR_OF_DAY);
const moh = this.fieldValues.get(ChronoField.MINUTE_OF_HOUR);
const som = this.fieldValues.get(ChronoField.SECOND_OF_MINUTE);
let nos = this.fieldValues.get(ChronoField.NANO_OF_SECOND);
if (hod == null) {
return;
}
if (moh == null && (som != null || nos != null)) {
return;
}
if (moh != null && som == null && nos != null) {
return;
}
if (resolverStyle !== ResolverStyle.LENIENT) {
if (hod != null) {
if (resolverStyle === ResolverStyle.SMART &&
hod === 24 &&
(moh == null || moh === 0) &&
(som == null || som === 0) &&
(nos == null || nos === 0)) {
hod = 0;
this.excessDays = Period.ofDays(1);
}
const hodVal = ChronoField.HOUR_OF_DAY.checkValidIntValue(hod);
if (moh != null) {
const mohVal = ChronoField.MINUTE_OF_HOUR.checkValidIntValue(moh);
if (som != null) {
const somVal = ChronoField.SECOND_OF_MINUTE.checkValidIntValue(som);
if (nos != null) {
const nosVal = ChronoField.NANO_OF_SECOND.checkValidIntValue(nos);
this._addObject(LocalTime.of(hodVal, mohVal, somVal, nosVal));
} else {
this._addObject(LocalTime.of(hodVal, mohVal, somVal));
}
} else {
if (nos == null) {
this._addObject(LocalTime.of(hodVal, mohVal));
}
}
} else {
if (som == null && nos == null) {
this._addObject(LocalTime.of(hodVal, 0));
}
}
}
} else {
if (hod != null) {
let hodVal = hod;
if (moh != null) {
if (som != null) {
if (nos == null) {
nos = 0;
}
let totalNanos = MathUtil.safeMultiply(hodVal, 3600000000000);
totalNanos = MathUtil.safeAdd(totalNanos, MathUtil.safeMultiply(moh, 60000000000));
totalNanos = MathUtil.safeAdd(totalNanos, MathUtil.safeMultiply(som, 1000000000));
totalNanos = MathUtil.safeAdd(totalNanos, nos);
const excessDays = MathUtil.floorDiv(totalNanos, 86400000000000); // safe int cast
const nod = MathUtil.floorMod(totalNanos, 86400000000000);
this._addObject(LocalTime.ofNanoOfDay(nod));
this.excessDays = Period.ofDays(excessDays);
} else {
let totalSecs = MathUtil.safeMultiply(hodVal, 3600);
totalSecs = MathUtil.safeAdd(totalSecs, MathUtil.safeMultiply(moh, 60));
const excessDays = MathUtil.floorDiv(totalSecs, 86400); // safe int cast
const sod = MathUtil.floorMod(totalSecs, 86400);
this._addObject(LocalTime.ofSecondOfDay(sod));
this.excessDays = Period.ofDays(excessDays);
}
} else {
const excessDays = MathUtil.safeToInt(MathUtil.floorDiv(hodVal, 24));
hodVal = MathUtil.floorMod(hodVal, 24);
this._addObject(LocalTime.of(hodVal, 0));
this.excessDays = Period.ofDays(excessDays);
}
}
}
this.fieldValues.remove(ChronoField.HOUR_OF_DAY);
this.fieldValues.remove(ChronoField.MINUTE_OF_HOUR);
this.fieldValues.remove(ChronoField.SECOND_OF_MINUTE);
this.fieldValues.remove(ChronoField.NANO_OF_SECOND);
}
/**
*
* @param {ChronoLocalDate|LocalTime} dateOrTime
* @private
*/
_addObject(dateOrTime) {
if (dateOrTime instanceof ChronoLocalDate){
this.date = dateOrTime;
} else if (dateOrTime instanceof LocalTime){
this.time = dateOrTime;
}
}
_resolveInstant() {
if (this.date != null && this.time != null) {
const offsetSecs = this.fieldValues.get(ChronoField.OFFSET_SECONDS);
if (offsetSecs != null) {
const offset = ZoneOffset.ofTotalSeconds(offsetSecs);
const instant = this.date.atTime(this.time).atZone(offset).getLong(ChronoField.INSTANT_SECONDS);
this.fieldValues.put(ChronoField.INSTANT_SECONDS, instant);
} else if (this.zone != null) {
const instant = this.date.atTime(this.time).atZone(this.zone).getLong(ChronoField.INSTANT_SECONDS);
this.fieldValues.put(ChronoField.INSTANT_SECONDS, instant);
}
}
}
/**
* Builds the specified type from the values in this builder.
*
* This attempts to build the specified type from this builder.
* If the builder cannot return the type, an exception is thrown.
*
* @param {!TemporalQuery} type - the type to invoke `from` on, not null
* @return {*} the extracted value, not null
* @throws DateTimeException if an error occurs
*/
build(type) {
return type.queryFrom(this);
}
/**
*
* @param {TemporalField} field
* @returns {number}
*/
isSupported(field) {
if (field == null) {
return false;
}
return (this.fieldValues.containsKey(field) && this.fieldValues.get(field) !== undefined) ||
(this.date != null && this.date.isSupported(field)) ||
(this.time != null && this.time.isSupported(field));
}
/**
*
* @param {TemporalField} field
* @returns {number}
*/
getLong(field) {
requireNonNull(field, 'field');
const value = this.getFieldValue0(field);
if (value == null) {
if (this.date != null && this.date.isSupported(field)) {
return this.date.getLong(field);
}
if (this.time != null && this.time.isSupported(field)) {
return this.time.getLong(field);
}
throw new DateTimeException(`Field not found: ${field}`);
}
return value;
}
/**
*
* @param {!TemporalQuery} query
* @returns {*}
*/
query(query) {
if (query === TemporalQueries.zoneId()) {
return this.zone;
} else if (query === TemporalQueries.chronology()) {
return this.chrono;
} else if (query === TemporalQueries.localDate()) {
return this.date != null ? LocalDate.from(this.date) : null;
} else if (query === TemporalQueries.localTime()) {
return this.time;
} else if (query === TemporalQueries.zone() || query === TemporalQueries.offset()) {
return query.queryFrom(this);
} else if (query === TemporalQueries.precision()) {
return null; // not a complete date/time
}
// inline TemporalAccessor.super.query(query) as an optimization
// non-JDK classes are not permitted to make this optimization
return query.queryFrom(this);
}
}

View File

@@ -0,0 +1,749 @@
/**
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
import { assert, requireNonNull } from '../assert';
import { DateTimeParseException, NullPointerException } from '../errors';
import { Period } from '../Period';
import { ParsePosition } from './ParsePosition';
import { DateTimeBuilder } from './DateTimeBuilder';
import { DateTimeParseContext } from './DateTimeParseContext';
import { DateTimePrintContext } from './DateTimePrintContext';
import { DateTimeFormatterBuilder } from './DateTimeFormatterBuilder';
import { SignStyle } from './SignStyle';
import { StringBuilder } from './StringBuilder';
import { ResolverStyle } from './ResolverStyle';
import { IsoChronology } from '../chrono/IsoChronology';
import { ChronoField } from '../temporal/ChronoField';
import { createTemporalQuery } from '../temporal/TemporalQuery';
/**
*
* ### Static properties of Class {@link DateTimeFormatter}
*
* DateTimeFormatter.ISO_LOCAL_DATE
*
* DateTimeFormatter.ISO_LOCAL_TIME
*
* DateTimeFormatter.ISO_LOCAL_DATE_TIME
*
*/
export class DateTimeFormatter {
//-----------------------------------------------------------------------
/**
* A query that provides access to the excess days that were parsed.
*
* This returns a singleton {@link TemporalQuery} that provides
* access to additional information from the parse. The query always returns
* a non-null period, with a zero period returned instead of null.
*
* There are two situations where this query may return a non-zero period.
*
* * If the {@link ResolverStyle} is {@link LENIENT} and a time is parsed
* without a date, then the complete result of the parse consists of a
* {@link LocalTime} and an excess {@link Period} in days.
* * If the {@link ResolverStyle} is {@link SMART} and a time is parsed
* without a date where the time is 24:00:00, then the complete result of
* the parse consists of a {@link LocalTime} of 00:00:00 and an excess
* {@link Period} of one day.
*
* In both cases, if a complete {@link ChronoLocalDateTime} or {@link Instant}
* is parsed, then the excess days are added to the date part.
* As a result, this query will return a zero period.
*
* The {@link SMART} behaviour handles the common "end of day" 24:00 value.
* Processing in {@link LENIENT} mode also produces the same result:
* <pre>
* Text to parse Parsed object Excess days
* "2012-12-03T00:00" LocalDateTime.of(2012, 12, 3, 0, 0) ZERO
* "2012-12-03T24:00" LocalDateTime.of(2012, 12, 4, 0, 0) ZERO
* "00:00" LocalTime.of(0, 0) ZERO
* "24:00" LocalTime.of(0, 0) Period.ofDays(1)
* </pre>
* The query can be used as follows:
* <pre>
* TemporalAccessor parsed = formatter.parse(str);
* LocalTime time = parsed.query(LocalTime.FROM);
* Period extraDays = parsed.query(DateTimeFormatter.parsedExcessDays());
* </pre>
* @return {TemporalQuery} a query that provides access to the excess days that were parsed
*/
static parsedExcessDays() {
return DateTimeFormatter.PARSED_EXCESS_DAYS;
}
/**
* A query that provides access to whether a leap-second was parsed.
*
* This returns a singleton {@link TemporalQuery} that provides
* access to additional information from the parse. The query always returns
* a non-null boolean, true if parsing saw a leap-second, false if not.
*
* Instant parsing handles the special "leap second" time of '23:59:60'.
* Leap seconds occur at '23:59:60' in the UTC time-zone, but at other
* local times in different time-zones. To avoid this potential ambiguity,
* the handling of leap-seconds is limited to
* {@link DateTimeFormatterBuilder#appendInstant}, as that method
* always parses the instant with the UTC zone offset.
*
* If the time '23:59:60' is received, then a simple conversion is applied,
* replacing the second-of-minute of 60 with 59. This query can be used
* on the parse result to determine if the leap-second adjustment was made.
* The query will return one second of excess if it did adjust to remove
* the leap-second, and zero if not. Note that applying a leap-second
* smoothing mechanism, such as UTC-SLS, is the responsibility of the
* application, as follows:
* <pre>
* TemporalAccessor parsed = formatter.parse(str);
* Instant instant = parsed.query(Instant::from);
* if (parsed.query(DateTimeFormatter.parsedLeapSecond())) {
* // validate leap-second is correct and apply correct smoothing
* }
* </pre>
* @return a query that provides access to whether a leap-second was parsed
*/
static parsedLeapSecond() {
return DateTimeFormatter.PARSED_LEAP_SECOND;
}
/**
* Creates a formatter using the specified pattern.
*
* This method will create a formatter based on a simple pattern of letters and symbols.
*
* The returned formatter will use the default locale, but this can be changed
* using {@link DateTimeFormatter.withLocale}.
*
* All letters 'A' to 'Z' and 'a' to 'z' are reserved as pattern letters.
* The following pattern letters are defined:
* <pre>
* |Symbol |Meaning |Presentation |Examples
* |--------|----------------------------|------------------|----------------------------------------------------
* | G | era | number/text | 1; 01; AD; Anno Domini
* | u | year | year | 2004; 04
* | y | year-of-era | year | 2004; 04
* | D | day-of-year | number | 189
* | M | month-of-year | number/text | 7; 07; Jul; July; J
* | d | day-of-month | number | 10
* | | | |
* | Q | quarter-of-year | number/text | 3; 03; Q3
* | Y | week-based-year | year | 1996; 96
* | w | week-of-year | number | 27
* | W | week-of-month | number | 27
* | e | localized day-of-week | number | 2; Tue; Tuesday; T
* | E | day-of-week | number/text | 2; Tue; Tuesday; T
* | F | week-of-month | number | 3
* | | | |
* | a | am-pm-of-day | text | PM
* | h | clock-hour-of-am-pm (1-12) | number | 12
* | K | hour-of-am-pm (0-11) | number | 0
* | k | clock-hour-of-am-pm (1-24) | number | 0
* | | | |
* | H | hour-of-day (0-23) | number | 0
* | m | minute-of-hour | number | 30
* | s | second-of-minute | number | 55
* | S | fraction-of-second | fraction | 978
* | A | milli-of-day | number | 1234
* | n | nano-of-second | number | 987654321
* | N | nano-of-day | number | 1234000000
* | | | |
* | V | time-zone ID | zone-id | America/Los_Angeles; Z; -08:30
* | z | time-zone name | zone-name | Pacific Standard Time; PST
* | X | zone-offset 'Z' for zero | offset-X | Z; -08; -0830; -08:30; -083015; -08:30:15;
* | x | zone-offset | offset-x | +0000; -08; -0830; -08:30; -083015; -08:30:15;
* | Z | zone-offset | offset-Z | +0000; -0800; -08:00;
* | | | |
* | p | pad next | pad modifier | 1
* | | | |
* | ' | escape for text | delimiter |
* | '' | single quote | literal | '
* | [ | optional section start | |
* | ] | optional section end | |
* | {} | reserved for future use | |
* </pre>
*
* The count of pattern letters determine the format.
*
* **Text**: The text style is determined based on the number of pattern letters used.
* Less than 4 pattern letters will use the short form `TextStyle.SHORT`.
* Exactly 4 pattern letters will use the full form `TextStyle.FULL`.
* Exactly 5 pattern letters will use the narrow form `TextStyle.NARROW`.
*
* **NOTE**: since text styles require locale support, they are currently not supported in js-joda!
*
* **Number**: If the count of letters is one, then the value is printed using the minimum number
* of digits and without padding as per {@link DateTimeFormatterBuilder.appendValue}.
* Otherwise, the count of digits is used as the width of the output field as per
* {@link DateTimeFormatterBuilder.appendValue}.
*
* **Number/Text**: If the count of pattern letters is 3 or greater, use the Text rules above.
* Otherwise use the Number rules above.
*
* **Fraction**: Outputs the nano-of-second field as a fraction-of-second.
* The nano-of-second value has nine digits, thus the count of pattern letters is from 1 to 9.
* If it is less than 9, then the nano-of-second value is truncated, with only the most
* significant digits being output.
* When parsing in strict mode, the number of parsed digits must match the count of pattern letters.
* When parsing in lenient mode, the number of parsed digits must be at least the count of pattern
* letters, up to 9 digits.
*
* **Year**: The count of letters determines the minimum field width below which padding is used.
* If the count of letters is two, then a {@link DateTimeFormatterBuilder.appendValueReduced}
* two digit form is used.
* For printing, this outputs the rightmost two digits. For parsing, this will parse using the
* base value of 2000, resulting in a year within the range 2000 to 2099 inclusive.
* If the count of letters is less than four (but not two), then the sign is only output for negative
* years as per `SignStyle.NORMAL`.
* Otherwise, the sign is output if the pad width is exceeded, as per `SignStyle.EXCEEDS_PAD`
*
* **ZoneId**: This outputs the time-zone ID, such as 'Europe/Paris'.
* If the count of letters is two, then the time-zone ID is output.
* Any other count of letters throws `IllegalArgumentException`.
*
* **Zone names**: This outputs the display name of the time-zone ID.
* If the count of letters is one, two or three, then the short name is output.
* If the count of letters is four, then the full name is output.
* Five or more letters throws `IllegalArgumentException`.
*
* **NOTE**: since zone ids and name require the iana tzdb, they are currently not supported in js-joda!
*
* **Offset X and x**: This formats the offset based on the number of pattern letters.
* One letter outputs just the hour', such as '+01', unless the minute is non-zero
* in which case the minute is also output, such as '+0130'.
* Two letters outputs the hour and minute, without a colon, such as '+0130'.
* Three letters outputs the hour and minute, with a colon, such as '+01:30'.
* Four letters outputs the hour and minute and optional second, without a colon, such as '+013015'.
* Five letters outputs the hour and minute and optional second, with a colon, such as '+01:30:15'.
* Six or more letters throws `IllegalArgumentException`.
* Pattern letter 'X' (upper case) will output 'Z' when the offset to be output would be zero,
* whereas pattern letter 'x' (lower case) will output '+00', '+0000', or '+00:00'.
*
* **Offset Z**: This formats the offset based on the number of pattern letters.
* One, two or three letters outputs the hour and minute, without a colon, such as '+0130'.
* Four or more letters throws `IllegalArgumentException`.
* The output will be '+0000' when the offset is zero.
*
* **Optional section**: The optional section markers work exactly like calling
* {@link DateTimeFormatterBuilder.optionalStart} and {@link DateTimeFormatterBuilder.optionalEnd}.
*
* **Pad modifier**: Modifies the pattern that immediately follows to be padded with spaces.
* The pad width is determined by the number of pattern letters.
* This is the same as calling {@link DateTimeFormatterBuilder.padNext}.
*
* For example, 'ppH' outputs the hour-of-day padded on the left with spaces to a width of 2.
*
* Any unrecognized letter is an error.
* Any non-letter character, other than '[', ']', '{', '}' and the single quote will be output directly.
* Despite this, it is recommended to use single quotes around all characters that you want to
* output directly to ensure that future changes do not break your application.
*
* @param {String} pattern the pattern to use, not null
* @return {DateTimeFormatter} the formatter based on the pattern, not null
* @throws IllegalArgumentException if the pattern is invalid
* @see DateTimeFormatterBuilder#appendPattern(String)
* @example
* var s = LocalDate.parse('2016-04-01').format(DateTimeFormatter.ofPattern('d MM yyyy'));
* console.log(s); // '1 04 2016'
*
*/
static ofPattern(pattern) {
return new DateTimeFormatterBuilder().appendPattern(pattern).toFormatter();
}
//-----------------------------------------------------------------------
/**
* Constructor.
*
* @param printerParser the printer/parser to use, not null
* @param locale the locale to use, not null
* @param decimalStyle the decimal style to use, not null
* @param resolverStyle the resolver style to use, not null
* @param resolverFields the fields to use during resolving, null for all fields
* @param chrono the chronology to use, null for no override
* @param zone the zone to use, null for no override
* @private
*/
constructor(printerParser, locale, decimalStyle, resolverStyle, resolverFields, chrono=IsoChronology.INSTANCE, zone) {
assert(printerParser != null);
assert(decimalStyle != null);
assert(resolverStyle != null);
/**
* The printer and/or parser to use, not null.
*/
this._printerParser = printerParser;
/**
* The locale to use for formatting. // nyi
*/
this._locale = locale;
/**
* The symbols to use for formatting, not null.
*/
this._decimalStyle = decimalStyle;
/**
* The resolver style to use, not null.
*/
this._resolverStyle = resolverStyle;
/**
* The fields to use in resolving, null for all fields.
*/
this._resolverFields = resolverFields;
/**
* The chronology to use for formatting, null for no override.
*/
this._chrono = chrono;
/**
* The zone to use for formatting, null for no override. // nyi
*/
this._zone = zone;
}
locale() {
return this._locale;
}
decimalStyle() {
return this._decimalStyle;
}
chronology() {
return this._chrono;
}
/**
* Returns a copy of this formatter with a new override chronology.
*
* This returns a formatter with similar state to this formatter but
* with the override chronology set.
* By default, a formatter has no override chronology, returning null.
*
* If an override is added, then any date that is printed or parsed will be affected.
*
* When printing, if the {@link Temporal} object contains a date then it will
* be converted to a date in the override chronology.
* Any time or zone will be retained unless overridden.
* The converted result will behave in a manner equivalent to an implementation
* of {@link ChronoLocalDate},{@link ChronoLocalDateTime} or {@link ChronoZonedDateTime}.
*
* When parsing, the override chronology will be used to interpret the
* {@link ChronoField} into a date unless the
* formatter directly parses a valid chronology.
*
* This instance is immutable and unaffected by this method call.
*
* @param chrono the new chronology, not null
* @return a formatter based on this formatter with the requested override chronology, not null
*/
withChronology(chrono) {
if (this._chrono != null && this._chrono.equals(chrono)) {
return this;
}
return new DateTimeFormatter(this._printerParser, this._locale, this._decimalStyle,
this._resolverStyle, this._resolverFields, chrono, this._zone);
}
/**
* not yet supported
* @returns {DateTimeFormatter}
*/
withLocale(){
return this;
}
/**
* Returns a copy of this formatter with a new resolver style.
* <p>
* This returns a formatter with similar state to this formatter but
* with the resolver style set. By default, a formatter has the
* {@link ResolverStyle#SMART SMART} resolver style.
* <p>
* Changing the resolver style only has an effect during parsing.
* Parsing a text string occurs in two phases.
* Phase 1 is a basic text parse according to the fields added to the builder.
* Phase 2 resolves the parsed field-value pairs into date and/or time objects.
* The resolver style is used to control how phase 2, resolving, happens.
* See {@link ResolverStyle} for more information on the options available.
* <p>
* This instance is immutable and unaffected by this method call.
*
* @param {ResolverStyle} resolverStyle the new resolver style, not null
* @return {DateTimeFormatter} a formatter based on this formatter with the requested resolver style, not null
*/
withResolverStyle(resolverStyle) {
requireNonNull(resolverStyle, 'resolverStyle');
if (resolverStyle.equals(this._resolverStyle)) {
return this;
}
return new DateTimeFormatter(this._printerParser, this._locale, this._decimalStyle, resolverStyle, this._resolverFields, this._chrono, this._zone);
}
//-----------------------------------------------------------------------
/**
* Formats a date-time object using this formatter.
*
* This formats the date-time to a String using the rules of the formatter.
*
* @param {TemporalAccessor} temporal the temporal object to print, not null
* @return {String} the printed string, not null
* @throws DateTimeException if an error occurs during formatting
*/
format(temporal) {
const buf = new StringBuilder(32);
this._formatTo(temporal, buf);
return buf.toString();
}
//-----------------------------------------------------------------------
/**
* Formats a date-time object to an {@link Appendable} using this formatter.
*
* This formats the date-time to the specified destination.
* {@link Appendable} is a general purpose interface that is implemented by all
* key character output classes including {@link StringBuffer}, {@link StringBuilder},
* {@link PrintStream} and {@link Writer}.
*
* Although {@link Appendable} methods throw an {@link IOException}, this method does not.
* Instead, any {@link IOException} is wrapped in a runtime exception.
*
* @param {TemporalAccessor} temporal - the temporal object to print, not null
* @param {StringBuilder} appendable - the appendable to print to, not null
* @throws DateTimeException if an error occurs during formatting
*/
_formatTo(temporal, appendable) {
requireNonNull(temporal, 'temporal');
requireNonNull(appendable, 'appendable');
const context = new DateTimePrintContext(temporal, this);
this._printerParser.print(context, appendable);
}
/**
* function overloading for {@link DateTimeFormatter.parse}
*
* if called with one arg {@link DateTimeFormatter.parse1} is called
* otherwise {@link DateTimeFormatter.parse2}
*
* @param {string} text
* @param {TemporalQuery} type
* @return {TemporalAccessor}
*/
parse(text, type){
if(arguments.length === 1){
return this.parse1(text);
} else {
return this.parse2(text, type);
}
}
/**
* Fully parses the text producing a temporal object.
*
* This parses the entire text producing a temporal object.
* It is typically more useful to use {@link parse}.
* The result of this method is {@link TemporalAccessor} which has been resolved,
* applying basic validation checks to help ensure a valid date-time.
*
* If the parse completes without reading the entire length of the text,
* or a problem occurs during parsing or merging, then an exception is thrown.
*
* @param {String} text the text to parse, not null
* @return {TemporalAccessor} the parsed temporal object, not null
* @throws DateTimeParseException if unable to parse the requested result
*/
parse1(text) {
requireNonNull(text, 'text');
try {
return this._parseToBuilder(text, null).resolve(this._resolverStyle, this._resolverFields);
} catch (ex) {
if(ex instanceof DateTimeParseException){
throw ex;
} else {
throw this._createError(text, ex);
}
}
}
/**
* Fully parses the text producing a temporal object.
*
* This parses the entire text producing a temporal object.
* It is typically more useful to use {@link parse}.
* The result of this method is {@link TemporalAccessor} which has been resolved,
* applying basic validation checks to help ensure a valid date-time.
*
* If the parse completes without reading the entire length of the text,
* or a problem occurs during parsing or merging, then an exception is thrown.
*
* @param text the text to parse, not null
* @param type the type to extract, not null
* @return the parsed temporal object, not null
* @throws DateTimeParseException if unable to parse the requested result
*/
parse2(text, type) {
requireNonNull(text, 'text');
requireNonNull(type, 'type');
try {
const builder = this._parseToBuilder(text, null).resolve(this._resolverStyle, this._resolverFields);
return builder.build(type);
} catch (ex) {
if(ex instanceof DateTimeParseException){
throw ex;
} else {
throw this._createError(text, ex);
}
}
}
_createError(text, ex) {
let abbr = '';
if (text.length > 64) {
abbr = `${text.substring(0, 64)}...`;
} else {
abbr = text;
}
return new DateTimeParseException(`Text '${abbr}' could not be parsed: ${ex.message}`, text, 0, ex);
}
/**
* Parses the text to a builder.
*
* This parses to a {@link DateTimeBuilder} ensuring that the text is fully parsed.
* This method throws {@link DateTimeParseException} if unable to parse, or
* some other {@link DateTimeException} if another date/time problem occurs.
*
* @param text the text to parse, not null
* @param position the position to parse from, updated with length parsed
* and the index of any error, null if parsing whole string
* @return the engine representing the result of the parse, not null
* @throws DateTimeParseException if the parse fails
*/
_parseToBuilder(text, position) {
const pos = (position != null ? position : new ParsePosition(0));
const result = this._parseUnresolved0(text, pos);
if (result == null || pos.getErrorIndex() >= 0 || (position == null && pos.getIndex() < text.length)) {
let abbr = '';
if (text.length > 64) {
abbr = `${text.substr(0, 64).toString()}...`;
} else {
abbr = text;
}
if (pos.getErrorIndex() >= 0) {
throw new DateTimeParseException(`Text '${abbr}' could not be parsed at index ${
pos.getErrorIndex()}`, text, pos.getErrorIndex());
} else {
throw new DateTimeParseException(`Text '${abbr}' could not be parsed, unparsed text found at index ${
pos.getIndex()}`, text, pos.getIndex());
}
}
return result.toBuilder();
}
/**
* Parses the text using this formatter, without resolving the result, intended
* for advanced use cases.
*
* Parsing is implemented as a two-phase operation.
* First, the text is parsed using the layout defined by the formatter, producing
* a {@link Map} of field to value, a {@link ZoneId} and a {@link Chronology}.
* Second, the parsed data is *resolved*, by validating, combining and
* simplifying the various fields into more useful ones.
* This method performs the parsing stage but not the resolving stage.
*
* The result of this method is {@link TemporalAccessor} which represents the
* data as seen in the input. Values are not validated, thus parsing a date string
* of '2012-00-65' would result in a temporal with three fields - year of '2012',
* month of '0' and day-of-month of '65'.
*
* The text will be parsed from the specified start {@link ParsePosition}.
* The entire length of the text does not have to be parsed, the {@link ParsePosition}
* will be updated with the index at the end of parsing.
*
* Errors are returned using the error index field of the {@link ParsePosition}
* instead of {@link DateTimeParseException}.
* The returned error index will be set to an index indicative of the error.
* Callers must check for errors before using the context.
*
* If the formatter parses the same field more than once with different values,
* the result will be an error.
*
* This method is intended for advanced use cases that need access to the
* internal state during parsing. Typical application code should use
* {@link parse} or the parse method on the target type.
*
* @param text the text to parse, not null
* @param position the position to parse from, updated with length parsed
* and the index of any error, not null
* @return the parsed text, null if the parse results in an error
* @throws DateTimeException if some problem occurs during parsing
* @throws IndexOutOfBoundsException if the position is invalid
*/
parseUnresolved(text, position) {
return this._parseUnresolved0(text, position);
}
_parseUnresolved0(text, position) {
assert(text != null, 'text', NullPointerException);
assert(position != null, 'position', NullPointerException);
const context = new DateTimeParseContext(this);
let pos = position.getIndex();
pos = this._printerParser.parse(context, text, pos);
if (pos < 0) {
position.setErrorIndex(~pos); // index not updated from input
return null;
}
position.setIndex(pos); // errorIndex not updated from input
return context.toParsed();
}
/**
* Returns the formatter as a composite printer parser.
*
* @param {boolean} optional whether the printer/parser should be optional
* @return {CompositePrinterParser} the printer/parser, not null
*/
_toPrinterParser(optional) {
return this._printerParser.withOptional(optional);
}
/**
*
* @returns {string}
*/
toString() {
const pattern = this._printerParser.toString();
return pattern.indexOf('[') === 0 ? pattern : pattern.substring(1, pattern.length - 1);
}
}
export function _init() {
DateTimeFormatter.ISO_LOCAL_DATE = new DateTimeFormatterBuilder()
.appendValue(ChronoField.YEAR, 4, 10, SignStyle.EXCEEDS_PAD)
.appendLiteral('-')
.appendValue(ChronoField.MONTH_OF_YEAR, 2)
.appendLiteral('-')
.appendValue(ChronoField.DAY_OF_MONTH, 2)
.toFormatter(ResolverStyle.STRICT).withChronology(IsoChronology.INSTANCE);
DateTimeFormatter.ISO_LOCAL_TIME = new DateTimeFormatterBuilder()
.appendValue(ChronoField.HOUR_OF_DAY, 2)
.appendLiteral(':')
.appendValue(ChronoField.MINUTE_OF_HOUR, 2)
.optionalStart()
.appendLiteral(':')
.appendValue(ChronoField.SECOND_OF_MINUTE, 2)
.optionalStart()
.appendFraction(ChronoField.NANO_OF_SECOND, 0, 9, true)
.toFormatter(ResolverStyle.STRICT);
DateTimeFormatter.ISO_LOCAL_DATE_TIME = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.append(DateTimeFormatter.ISO_LOCAL_DATE)
.appendLiteral('T')
.append(DateTimeFormatter.ISO_LOCAL_TIME)
.toFormatter(ResolverStyle.STRICT).withChronology(IsoChronology.INSTANCE);
DateTimeFormatter.ISO_INSTANT = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendInstant()
.toFormatter(ResolverStyle.STRICT);
DateTimeFormatter.ISO_OFFSET_DATE_TIME = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.append(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
.appendOffsetId()
.toFormatter(ResolverStyle.STRICT).withChronology(IsoChronology.INSTANCE);
DateTimeFormatter.ISO_ZONED_DATE_TIME = new DateTimeFormatterBuilder()
.append(DateTimeFormatter.ISO_OFFSET_DATE_TIME)
.optionalStart()
.appendLiteral('[')
.parseCaseSensitive()
.appendZoneId()
// .appendZoneRegionId()
.appendLiteral(']')
.toFormatter(ResolverStyle.STRICT).withChronology(IsoChronology.INSTANCE);
DateTimeFormatter.BASIC_ISO_DATE = new DateTimeFormatterBuilder()
.appendValue(ChronoField.YEAR, 4, 10, SignStyle.EXCEEDS_PAD)
.appendValue(ChronoField.MONTH_OF_YEAR, 2)
.appendValue(ChronoField.DAY_OF_MONTH, 2)
.toFormatter(ResolverStyle.STRICT).withChronology(IsoChronology.INSTANCE);
DateTimeFormatter.ISO_OFFSET_DATE = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.append(DateTimeFormatter.ISO_LOCAL_DATE)
.appendOffsetId()
.toFormatter(ResolverStyle.STRICT).withChronology(IsoChronology.INSTANCE);
DateTimeFormatter.ISO_OFFSET_TIME = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.append(DateTimeFormatter.ISO_LOCAL_TIME)
.appendOffsetId()
.toFormatter(ResolverStyle.STRICT).withChronology(IsoChronology.INSTANCE);
DateTimeFormatter.ISO_ORDINAL_DATE = new DateTimeFormatterBuilder()
.appendValue(ChronoField.YEAR, 4, 10, SignStyle.EXCEEDS_PAD)
.appendLiteral('-')
.appendValue(ChronoField.DAY_OF_YEAR)
.toFormatter(ResolverStyle.STRICT);
DateTimeFormatter.ISO_WEEK_DATE = new DateTimeFormatterBuilder()
.appendValue(ChronoField.YEAR, 4, 10, SignStyle.EXCEEDS_PAD)
.appendLiteral('-W')
.appendValue(ChronoField.ALIGNED_WEEK_OF_YEAR)
.appendLiteral('-')
.appendValue(ChronoField.DAY_OF_WEEK)
.toFormatter(ResolverStyle.STRICT);
DateTimeFormatter.ISO_DATE = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.append(DateTimeFormatter.ISO_LOCAL_DATE)
.optionalStart()
.appendOffsetId()
.optionalEnd()
.toFormatter(ResolverStyle.STRICT).withChronology(IsoChronology.INSTANCE);
DateTimeFormatter.ISO_TIME = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.append(DateTimeFormatter.ISO_LOCAL_TIME)
.optionalStart()
.appendOffsetId()
.optionalEnd()
.toFormatter(ResolverStyle.STRICT);
DateTimeFormatter.ISO_DATE_TIME = new DateTimeFormatterBuilder()
.append(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
.optionalStart()
.appendOffsetId()
.optionalEnd()
.toFormatter(ResolverStyle.STRICT).withChronology(IsoChronology.INSTANCE);
// TODO:
// RFC_1123_DATE_TIME - https://www.threeten.org/threetenbp/apidocs/org/threeten/bp/format/DateTimeFormatter.html#RFC_1123_DATE_TIME
DateTimeFormatter.PARSED_EXCESS_DAYS = createTemporalQuery('PARSED_EXCESS_DAYS', (temporal) => {
if (temporal instanceof DateTimeBuilder) {
return temporal.excessDays;
} else {
return Period.ZERO;
}
});
DateTimeFormatter.PARSED_LEAP_SECOND = createTemporalQuery('PARSED_LEAP_SECOND', (temporal) => {
if (temporal instanceof DateTimeBuilder) {
return temporal.leapSecond;
} else {
return false;
}
});
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,297 @@
/*
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
import { assert, requireNonNull } from '../assert';
import { DateTimeBuilder } from './DateTimeBuilder';
import { EnumMap } from './EnumMap';
import { IsoChronology } from '../chrono/IsoChronology';
import { Temporal } from '../temporal/Temporal';
import { TemporalQueries } from '../temporal/TemporalQueries';
/**
* @private
*/
export class DateTimeParseContext{
constructor(){
if(arguments.length === 1){
if(arguments[0] instanceof DateTimeParseContext){
this._constructorSelf.apply(this, arguments);
return;
} else {
this._constructorFormatter.apply(this, arguments);
}
} else {
this._constructorParam.apply(this, arguments);
}
this._caseSensitive = true;
this._strict = true;
this._parsed = [new Parsed(this)];
}
_constructorParam(locale, symbols, chronology){
this._locale = locale;
this._symbols = symbols;
this._overrideChronology = chronology;
}
_constructorFormatter(formatter){
this._locale = formatter.locale();
this._symbols = formatter.decimalStyle();
this._overrideChronology = formatter.chronology();
}
_constructorSelf(other) {
this._locale = other._locale;
this._symbols = other._symbols;
this._overrideChronology = other._overrideChronology;
this._overrideZone = other._overrideZone;
this._caseSensitive = other._caseSensitive;
this._strict = other._strict;
this._parsed = [new Parsed(this)];
}
/**
* Creates a copy of this context.
*/
copy() {
return new DateTimeParseContext(this);
}
symbols(){
return this._symbols;
}
isStrict(){
return this._strict;
}
setStrict(strict){
this._strict = strict;
}
locale() {
return this._locale;
}
setLocale(locale) {
this._locale = locale;
}
//-----------------------------------------------------------------------
/**
* Starts the parsing of an optional segment of the input.
*/
startOptional() {
this._parsed.push(this.currentParsed().copy());
}
/**
* Ends the parsing of an optional segment of the input.
*
* @param {boolean} successful whether the optional segment was successfully parsed
*/
endOptional(successful) {
if (successful) {
this._parsed.splice(this._parsed.length - 2, 1);
} else {
this._parsed.splice(this._parsed.length - 1, 1);
}
}
/**
* Checks if parsing is case sensitive.
*
* @return true if parsing is case sensitive, false if case insensitive
*/
isCaseSensitive() {
return this._caseSensitive;
}
/**
* Sets whether the parsing is case sensitive or not.
*
* @param caseSensitive changes the parsing to be case sensitive or not from now on
*/
setCaseSensitive(caseSensitive) {
this._caseSensitive = caseSensitive;
}
/**
* Helper to compare two {@link CharSequence} instances.
* This uses {@link isCaseSensitive}.
*
* @param cs1 the first character sequence, not null
* @param offset1 the offset into the first sequence, valid
* @param cs2 the second character sequence, not null
* @param offset2 the offset into the second sequence, valid
* @param length the length to check, valid
* @return true if equal
*/
subSequenceEquals(cs1, offset1, cs2, offset2, length) {
if (offset1 + length > cs1.length || offset2 + length > cs2.length) {
return false;
}
if (! this.isCaseSensitive()) {
cs1 = cs1.toLowerCase();
cs2 = cs2.toLowerCase();
}
for (let i = 0; i < length; i++) {
const ch1 = cs1[offset1 + i];
const ch2 = cs2[offset2 + i];
if (ch1 !== ch2) {
return false;
}
}
return true;
}
/**
* Helper to compare two `char`.
* This uses {@link isCaseSensitive}.
*
* @param ch1 the first character
* @param ch2 the second character
* @return true if equal
*/
charEquals(ch1, ch2) {
if (this.isCaseSensitive()) {
return ch1 === ch2;
}
return this.charEqualsIgnoreCase(ch1, ch2);
}
/**
* Compares two characters ignoring case.
*
* @param c1 the first
* @param c2 the second
* @return true if equal
*/
charEqualsIgnoreCase(c1, c2) {
return c1 === c2 ||
c1.toLowerCase() === c2.toLowerCase();
}
setParsedField(field, value, errorPos, successPos){
const currentParsedFieldValues = this.currentParsed().fieldValues;
const old = currentParsedFieldValues.get(field);
currentParsedFieldValues.set(field, value);
return (old != null && old !== value) ? ~errorPos : successPos;
}
/**
* Stores the parsed zone.
*
* This stores the zone that has been parsed.
* No validation is performed other than ensuring it is not null.
*
* @param {ZoneId} zone the parsed zone, not null
*/
setParsedZone(zone) {
requireNonNull(zone, 'zone');
this.currentParsed().zone = zone;
}
getParsed(field) {
return this.currentParsed().fieldValues.get(field);
}
toParsed() {
return this.currentParsed();
}
currentParsed() {
return this._parsed[this._parsed.length - 1];
}
/**
* Stores the leap second.
*/
setParsedLeapSecond() {
this.currentParsed().leapSecond = true;
}
/**
* Gets the effective chronology during parsing.
*
* @return the effective parsing chronology, not null
*/
getEffectiveChronology() {
let chrono = this.currentParsed().chrono;
if (chrono == null) {
chrono = this._overrideChronology;
if (chrono == null) {
chrono = IsoChronology.INSTANCE;
}
}
return chrono;
}
}
class Parsed extends Temporal {
constructor(dateTimeParseContext){
super();
this.chrono = null;
this.zone = null;
this.fieldValues = new EnumMap();
this.leapSecond = false;
this.dateTimeParseContext = dateTimeParseContext;
}
copy() {
const cloned = new Parsed();
cloned.chrono = this.chrono;
cloned.zone = this.zone;
cloned.fieldValues.putAll(this.fieldValues);
cloned.leapSecond = this.leapSecond;
cloned.dateTimeParseContext = this.dateTimeParseContext;
return cloned;
}
toString() {
return `${this.fieldValues}, ${this.chrono}, ${this.zone}`;
}
isSupported(field) {
return this.fieldValues.containsKey(field);
}
get(field) {
const val = this.fieldValues.get(field);
assert(val != null);
return val;
}
query(query) {
if (query === TemporalQueries.chronology()) {
return this.chrono;
}
if (query === TemporalQueries.zoneId() || query === TemporalQueries.zone()) {
return this.zone;
}
return super.query(query);
}
toBuilder() {
const builder = new DateTimeBuilder();
builder.fieldValues.putAll(this.fieldValues);
builder.chrono = this.dateTimeParseContext.getEffectiveChronology();
if (this.zone != null) {
builder.zone = this.zone;
} else {
builder.zone = this.overrideZone;
}
builder.leapSecond = this.leapSecond;
builder.excessDays = this.excessDays;
return builder;
}
}

View File

@@ -0,0 +1,138 @@
/*
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
import { DateTimeException } from '../errors';
import { DateTimeFormatter } from './DateTimeFormatter';
/**
* @private
*/
export class DateTimePrintContext{
/**
*
* @param {TemporalAccessor} temporal
* @param {DateTimeFormatter|Locale} localeOrFormatter
* @param {DecimalStyle} symbols
*/
constructor(temporal, localeOrFormatter, symbols) {
if(arguments.length === 2 && arguments[1] instanceof DateTimeFormatter){
this._temporal = DateTimePrintContext.adjust(temporal, localeOrFormatter);
this._locale = localeOrFormatter.locale();
this._symbols = localeOrFormatter.decimalStyle();
} else {
this._temporal = temporal;
this._locale = localeOrFormatter;
this._symbols = symbols;
}
this._optional = 0;
}
/**
*
* @param {TemporalAccessor} temporal
* @param {DateTimeFormatter} formatter
* @returns {TemporalAccessor}
*/
// eslint-disable-next-line no-unused-vars
static adjust(temporal, formatter) {
// TODO implement
return temporal;
}
symbols(){
return this._symbols;
}
/**
* Starts the printing of an optional segment of the input.
*/
startOptional() {
this._optional++;
}
/**
* Ends the printing of an optional segment of the input.
*/
endOptional() {
this._optional--;
}
/**
* Gets a value using a query.
*
* @param {TemporalQuery} query the query to use, not null
* @return {*} the result, null if not found and optional is true
* @throws DateTimeException if the type is not available and the section is not optional
*/
getValueQuery(query) {
const result = this._temporal.query(query);
if (result == null && this._optional === 0) {
throw new DateTimeException(`Unable to extract value: ${this._temporal}`);
}
return result;
}
/**
* Gets the value of the specified field.
*
* This will return the value for the specified field.
*
* @param field the field to find, not null
* @return the value, null if not found and optional is true
* @throws DateTimeException if the field is not available and the section is not optional
*/
getValue(field) {
try {
return this._temporal.getLong(field);
} catch (ex) {
if ((ex instanceof DateTimeException) && this._optional > 0) {
return null;
}
throw ex;
}
}
//-----------------------------------------------------------------------
/**
* Gets the temporal object being output.
*
* @return {TemporalAccessor} the temporal object, not null
*/
temporal() {
return this._temporal;
}
/**
* Gets the locale.
* <p>
* This locale is used to control localization in the print output except
* where localization is controlled by the symbols.
*
* @return the locale, not null
*/
locale() {
return this._locale;
}
//-------------------------------------------------------------------------
// for testing
/**
* Sets the date-time being output.
*
* @param temporal the date-time object, not null
*/
setDateTime(temporal) {
this._temporal = temporal;
}
setLocale(locale) {
this._locale = locale;
}
}

113
node_modules/@js-joda/core/src/format/DecimalStyle.js generated vendored Normal file
View File

@@ -0,0 +1,113 @@
/**
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
export class DecimalStyle {
/**
*
* @param zeroChar
* @param positiveSignChar
* @param negativeSignChar
* @param decimalPointChar
* @private
*/
constructor(zeroChar, positiveSignChar, negativeSignChar, decimalPointChar) {
this._zeroDigit = zeroChar;
this._zeroDigitCharCode = zeroChar.charCodeAt(0);
this._positiveSign = positiveSignChar;
this._negativeSign = negativeSignChar;
this._decimalSeparator = decimalPointChar;
}
positiveSign(){
return this._positiveSign;
}
withPositiveSign(positiveSign) {
if (positiveSign === this._positiveSign) {
return this;
}
return new DecimalStyle(this._zeroDigit, positiveSign, this._negativeSign, this._decimalSeparator);
}
negativeSign(){
return this._negativeSign;
}
withNegativeSign(negativeSign) {
if (negativeSign === this._negativeSign) {
return this;
}
return new DecimalStyle(this._zeroDigit, this._positiveSign, negativeSign, this._decimalSeparator);
}
zeroDigit(){
return this._zeroDigit;
}
withZeroDigit(zeroDigit) {
if (zeroDigit === this._zeroDigit) {
return this;
}
return new DecimalStyle(zeroDigit, this._positiveSign, this._negativeSign, this._decimalSeparator);
}
decimalSeparator(){
return this._decimalSeparator;
}
withDecimalSeparator(decimalSeparator) {
if (decimalSeparator === this._decimalSeparator) {
return this;
}
return new DecimalStyle(this._zeroDigit, this._positiveSign, this._negativeSign, decimalSeparator);
}
convertToDigit(char){
const val = char.charCodeAt(0) - this._zeroDigitCharCode;
return (val >= 0 && val <= 9) ? val : -1;
}
convertNumberToI18N(numericText) {
if (this._zeroDigit === '0') {
return numericText;
}
const diff = this._zeroDigitCharCode - '0'.charCodeAt(0);
let convertedText = '';
for (let i = 0; i < numericText.length; i++) {
convertedText += String.fromCharCode(numericText.charCodeAt(i) + diff);
}
return convertedText;
}
equals(other) {
if (this === other) {
return true;
}
if (other instanceof DecimalStyle) {
return (this._zeroDigit === other._zeroDigit && this._positiveSign === other._positiveSign &&
this._negativeSign === other._negativeSign && this._decimalSeparator === other._decimalSeparator);
}
return false;
}
hashCode() {
return this._zeroDigit + this._positiveSign + this._negativeSign + this._decimalSeparator;
}
toString() {
return `DecimalStyle[${this._zeroDigit}${this._positiveSign}${this._negativeSign}${this._decimalSeparator}]`;
}
static of(){
throw new Error('not yet supported');
}
static availableLocales(){
throw new Error('not yet supported');
}
}
DecimalStyle.STANDARD = new DecimalStyle('0', '+', '-', '.');

70
node_modules/@js-joda/core/src/format/EnumMap.js generated vendored Normal file
View File

@@ -0,0 +1,70 @@
/*
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
/**
* @private
*/
export class EnumMap {
constructor(){
this._map = {};
}
putAll(otherMap){
for(const key in otherMap._map){
this._map[key] = otherMap._map[key];
}
return this;
}
containsKey(key){
// eslint-disable-next-line no-prototype-builtins
return (this._map.hasOwnProperty(key.name())) && (this.get(key) !== undefined);
}
get(key) {
return this._map[key.name()];
}
put(key, val) {
return this.set(key, val);
}
set(key, val) {
this._map[key.name()] = val;
return this;
}
retainAll(keyList){
const map = {};
for(let i=0; i<keyList.length; i++){
const key = keyList[i].name();
map[key] = this._map[key];
}
this._map = map;
return this;
}
/**
* due to the bad performance of delete we just set the key entry to undefined.
*
* this might lead to issues with "null" entries. Calling clear in the end might solve the issue
* @param key
* @returns {*}
*/
remove(key){
const keyName = key.name();
const val = this._map[keyName];
this._map[keyName] = undefined;
return val;
}
keySet(){
return this._map;
}
clear(){
this._map = {};
}
}

31
node_modules/@js-joda/core/src/format/ParsePosition.js generated vendored Normal file
View File

@@ -0,0 +1,31 @@
/*
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
/**
* @private
*/
export class ParsePosition {
constructor(index) {
this._index = index;
this._errorIndex = -1;
}
getIndex(){
return this._index;
}
setIndex(index){
this._index = index;
}
getErrorIndex(){
return this._errorIndex;
}
setErrorIndex(errorIndex){
this._errorIndex = errorIndex;
}
}

93
node_modules/@js-joda/core/src/format/ResolverStyle.js generated vendored Normal file
View File

@@ -0,0 +1,93 @@
/*
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
import { Enum } from '../Enum';
/**
* Enumeration of different ways to resolve dates and times.
*
* Parsing a text string occurs in two phases.
* Phase 1 is a basic text parse according to the fields added to the builder.
* Phase 2 resolves the parsed field-value pairs into date and/or time objects.
* This style is used to control how phase 2, resolving, happens.
*
* ### Static properties of Class {@link DateTimeFormatter}
*
* ResolverStyle.STRICT = new ResolverStyle('STRICT');
*
* Style to resolve dates and times strictly.
*
* Using strict resolution will ensure that all parsed values are within
* the outer range of valid values for the field. Individual fields may
* be further processed for strictness.
*
* For example, resolving year-month and day-of-month in the ISO calendar
* system using strict mode will ensure that the day-of-month is valid
* for the year-month, rejecting invalid values.
*
* ResolverStyle.SMART = new ResolverStyle('SMART');
*
* Style to resolve dates and times in a smart, or intelligent, manner.
*
* Using smart resolution will perform the sensible default for each
* field, which may be the same as strict, the same as lenient, or a third
* behavior. Individual fields will interpret this differently.
*
* For example, resolving year-month and day-of-month in the ISO calendar
* system using smart mode will ensure that the day-of-month is from
* 1 to 31, converting any value beyond the last valid day-of-month to be
* the last valid day-of-month.
*
* ResolverStyle.LENIENT = new ResolverStyle('LENIENT');
*
* Style to resolve dates and times leniently.
*
* Using lenient resolution will resolve the values in an appropriate
* lenient manner. Individual fields will interpret this differently.
*
* For example, lenient mode allows the month in the ISO calendar system
* to be outside the range 1 to 12.
* For example, month 15 is treated as being 3 months after month 12.
*
*/
export class ResolverStyle extends Enum {}
/**
* Style to resolve dates and times strictly.
*
* Using strict resolution will ensure that all parsed values are within
* the outer range of valid values for the field. Individual fields may
* be further processed for strictness.
*
* For example, resolving year-month and day-of-month in the ISO calendar
* system using strict mode will ensure that the day-of-month is valid
* for the year-month, rejecting invalid values.
*/
ResolverStyle.STRICT = new ResolverStyle('STRICT');
/**
* Style to resolve dates and times in a smart, or intelligent, manner.
*
* Using smart resolution will perform the sensible default for each
* field, which may be the same as strict, the same as lenient, or a third
* behavior. Individual fields will interpret this differently.
*
* For example, resolving year-month and day-of-month in the ISO calendar
* system using smart mode will ensure that the day-of-month is from
* 1 to 31, converting any value beyond the last valid day-of-month to be
* the last valid day-of-month.
*/
ResolverStyle.SMART = new ResolverStyle('SMART');
/**
* Style to resolve dates and times leniently.
*
* Using lenient resolution will resolve the values in an appropriate
* lenient manner. Individual fields will interpret this differently.
*
* For example, lenient mode allows the month in the ISO calendar system
* to be outside the range 1 to 12.
* For example, month 15 is treated as being 3 months after month 12.
*/
ResolverStyle.LENIENT = new ResolverStyle('LENIENT');

38
node_modules/@js-joda/core/src/format/SignStyle.js generated vendored Normal file
View File

@@ -0,0 +1,38 @@
/**
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
import { Enum } from '../Enum';
export class SignStyle extends Enum{
/**
* Parse helper.
*
* @param positive true if positive sign parsed, false for negative sign
* @param strict true if strict, false if lenient
* @param fixedWidth true if fixed width, false if not
* @return true if valid
*/
parse(positive, strict, fixedWidth){
switch (this) {
case SignStyle.NORMAL: // NORMAL
// valid if negative or (positive and lenient)
return !positive || !strict;
case SignStyle.ALWAYS: // ALWAYS
case SignStyle.EXCEEDS_PAD: // EXCEEDS_PAD
return true;
default:
// valid if lenient and not fixed width
return !strict && !fixedWidth;
}
}
}
SignStyle.NORMAL = new SignStyle('NORMAL');
SignStyle.NEVER = new SignStyle('NEVER');
SignStyle.ALWAYS = new SignStyle('ALWAYS');
SignStyle.EXCEEDS_PAD = new SignStyle('EXCEEDS_PAD');
SignStyle.NOT_NEGATIVE = new SignStyle('NOT_NEGATIVE');

47
node_modules/@js-joda/core/src/format/StringBuilder.js generated vendored Normal file
View File

@@ -0,0 +1,47 @@
/*
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
/**
* @private
*/
export class StringBuilder {
constructor(){
this._str = '';
}
append(str){
this._str += str;
return this;
}
appendChar(str){
this._str += str[0];
return this;
}
insert(offset, str){
this._str = this._str.slice(0, offset) + str + this._str.slice(offset);
return this;
}
replace(start, end, str){
this._str = this._str.slice(0, start) + str + this._str.slice(end);
return this;
}
length(){
return this._str.length;
}
setLength(length){
this._str = this._str.slice(0, length);
return this;
}
toString() {
return this._str;
}
}

114
node_modules/@js-joda/core/src/format/TextStyle.js generated vendored Normal file
View File

@@ -0,0 +1,114 @@
/*
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @license BSD-3-Clause (see LICENSE.md in the root directory of this source tree)
*/
import { Enum } from '../Enum';
/**
* Enumeration of the style of text formatting and parsing.
*
* Text styles define three sizes for the formatted text - 'full', 'short' and 'narrow'.
* Each of these three sizes is available in both 'standard' and 'stand-alone' variations.
*
* The difference between the three sizes is obvious in most languages.
* For example, in English the 'full' month is 'January', the 'short' month is 'Jan'
* and the 'narrow' month is 'J'. Note that the narrow size is often not unique.
* For example, 'January', 'June' and 'July' all have the 'narrow' text 'J'.
*
* The difference between the 'standard' and 'stand-alone' forms is trickier to describe
* as there is no difference in English. However, in other languages there is a difference
* in the word used when the text is used alone, as opposed to in a complete date.
* For example, the word used for a month when used alone in a date picker is different
* to the word used for month in association with a day and year in a date.
*
* ### Specification for implementors
*
* This is immutable and thread-safe enum.
*/
export class TextStyle extends Enum {
/**
* Checks if the style is stand-alone.
*
* @return {boolean} true if the style is stand-alone
*/
isStandalone() {
switch (this) {
case TextStyle.FULL_STANDALONE:
case TextStyle.SHORT_STANDALONE:
case TextStyle.NARROW_STANDALONE:
return true;
default:
return false;
}
}
/**
* Converts the style to the equivalent stand-alone style.
*
* @return {TextStyle} the matching stand-alone style
*/
asStandalone() {
switch (this) {
case TextStyle.FULL:
return TextStyle.FULL_STANDALONE;
case TextStyle.SHORT:
return TextStyle.SHORT_STANDALONE;
case TextStyle.NARROW:
return TextStyle.NARROW_STANDALONE;
default:
// all others are already standalone
return this;
}
}
/**
* Converts the style to the equivalent normal style.
*
* @return {TextStyle} the matching normal style
*/
asNormal() {
switch (this) {
case TextStyle.FULL_STANDALONE:
return TextStyle.FULL;
case TextStyle.SHORT_STANDALONE:
return TextStyle.SHORT;
case TextStyle.NARROW_STANDALONE:
return TextStyle.NARROW;
default:
// all others are already normal
return this;
}
}
}
/**
* Full text, typically the full description.
* For example, day-of-week Monday might output "Monday".
*/
TextStyle.FULL = new TextStyle('FULL');
/**
* Full text for stand-alone use, typically the full description.
* For example, day-of-week Monday might output "Monday".
*/
TextStyle.FULL_STANDALONE = new TextStyle('FULL_STANDALONE');
/**
* Short text, typically an abbreviation.
* For example, day-of-week Monday might output "Mon".
*/
TextStyle.SHORT = new TextStyle('SHORT');
/**
* Short text for stand-alone use, typically an abbreviation.
* For example, day-of-week Monday might output "Mon".
*/
TextStyle.SHORT_STANDALONE = new TextStyle('SHORT_STANDALONE');
/**
* Narrow text, typically a single letter.
* For example, day-of-week Monday might output "M".
*/
TextStyle.NARROW = new TextStyle('NARROW');
/**
* Narrow text for stand-alone use, typically a single letter.
* For example, day-of-week Monday might output "M".
*/
TextStyle.NARROW_STANDALONE = new TextStyle('NARROW_STANDALONE');

View File

@@ -0,0 +1,46 @@
/**
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
import { IllegalArgumentException } from '../../errors';
/**
* Prints or parses a char literal.
* @private
*/
export class CharLiteralPrinterParser {
constructor(literal) {
if (literal.length > 1) {
throw new IllegalArgumentException(`invalid literal, too long: "${literal}"`);
}
this._literal = literal;
}
print(context, buf) {
buf.append(this._literal);
return true;
}
parse(context, text, position) {
const length = text.length;
if (position === length) {
return ~position;
}
const ch = text.charAt(position);
if (context.charEquals(this._literal, ch) === false) {
return ~position;
}
return position + this._literal.length;
}
toString() {
if (this._literal === '\'') {
return "''";
}
return `'${this._literal}'`;
}
}

View File

@@ -0,0 +1,89 @@
/**
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
/**
* @private
*/
export class CompositePrinterParser {
constructor(printerParsers, optional) {
this._printerParsers = printerParsers;
this._optional = optional;
}
/**
* Returns a copy of this printer-parser with the optional flag changed.
*
* @param {boolean} optional the optional flag to set in the copy
* @return {CompositePrinterParser} the new printer-parser, not null
*/
withOptional(optional) {
if (optional === this._optional) {
return this;
}
return new CompositePrinterParser(this._printerParsers, optional);
}
print(context, buf) {
const length = buf.length();
if (this._optional) {
context.startOptional();
}
try {
for (let i=0; i<this._printerParsers.length; i++) {
const pp = this._printerParsers[i];
if (pp.print(context, buf) === false) {
buf.setLength(length); // reset buffer
return true;
}
}
} finally {
if (this._optional) {
context.endOptional();
}
}
return true;
}
parse(context, text, position) {
if (this._optional) {
context.startOptional();
let pos = position;
for (let i=0; i<this._printerParsers.length; i++) {
const pp = this._printerParsers[i];
pos = pp.parse(context, text, pos);
if (pos < 0) {
context.endOptional(false);
return position; // return original position
}
}
context.endOptional(true);
return pos;
} else {
for (let i=0; i<this._printerParsers.length; i++) {
const pp = this._printerParsers[i];
position = pp.parse(context, text, position);
if (position < 0) {
break;
}
}
return position;
}
}
toString() {
let buf = '';
if (this._printerParsers != null) {
buf += this._optional ? '[' : '(';
for (let i=0; i<this._printerParsers.length; i++) {
const pp = this._printerParsers[i];
buf += pp.toString();
}
buf += this._optional ? ']' : ')';
}
return buf;
}
}

View File

@@ -0,0 +1,162 @@
/**
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
import { requireNonNull } from '../../assert';
import { IllegalArgumentException } from '../../errors';
import { MathUtil } from '../../MathUtil';
/**
* TODO optimize FractionPrinterParser, fix documentation
*
* Prints and parses a numeric date-time field with optional padding.
* @private
*/
export class FractionPrinterParser {
/**
* Constructor.
*
* @param {TemporalField} field the field to output, not null
* @param {Number} minWidth the minimum width to output, from 0 to 9
* @param {Number} maxWidth the maximum width to output, from 0 to 9
* @param {boolean} decimalPoint whether to output the localized decimal point symbol
*/
constructor(field, minWidth, maxWidth, decimalPoint) {
requireNonNull(field, 'field');
if (field.range().isFixed() === false) {
throw new IllegalArgumentException(`Field must have a fixed set of values: ${field}`);
}
if (minWidth < 0 || minWidth > 9) {
throw new IllegalArgumentException(`Minimum width must be from 0 to 9 inclusive but was ${minWidth}`);
}
if (maxWidth < 1 || maxWidth > 9) {
throw new IllegalArgumentException(`Maximum width must be from 1 to 9 inclusive but was ${maxWidth}`);
}
if (maxWidth < minWidth) {
throw new IllegalArgumentException(`Maximum width must exceed or equal the minimum width but ${
maxWidth} < ${minWidth}`);
}
this.field = field;
this.minWidth = minWidth;
this.maxWidth = maxWidth;
this.decimalPoint = decimalPoint;
}
print(context, buf) {
const value = context.getValue(this.field);
if (value === null) {
return false;
}
const symbols = context.symbols();
if (value === 0) { // scale is zero if value is zero
if (this.minWidth > 0) {
if (this.decimalPoint) {
buf.append(symbols.decimalSeparator());
}
for (let i = 0; i < this.minWidth; i++) {
buf.append(symbols.zeroDigit());
}
}
} else {
let fraction = this.convertToFraction(value, symbols.zeroDigit());
const outputScale = Math.min(Math.max(fraction.length, this.minWidth), this.maxWidth);
fraction = fraction.substr(0, outputScale);
if(fraction * 1 > 0 ) {
while (fraction.length > this.minWidth && fraction[fraction.length - 1] === '0') {
fraction = fraction.substr(0, fraction.length - 1);
}
}
let str = fraction;
str = symbols.convertNumberToI18N(str);
if (this.decimalPoint) {
buf.append(symbols.decimalSeparator());
}
buf.append(str);
}
return true;
}
parse(context, text, position) {
const effectiveMin = (context.isStrict() ? this.minWidth : 0);
const effectiveMax = (context.isStrict() ? this.maxWidth : 9);
const length = text.length;
if (position === length) {
// valid if whole field is optional, invalid if minimum width
return (effectiveMin > 0 ? ~position : position);
}
if (this.decimalPoint) {
if (text[position] !== context.symbols().decimalSeparator()) {
// valid if whole field is optional, invalid if minimum width
return (effectiveMin > 0 ? ~position : position);
}
position++;
}
const minEndPos = position + effectiveMin;
if (minEndPos > length) {
return ~position; // need at least min width digits
}
const maxEndPos = Math.min(position + effectiveMax, length);
let total = 0; // can use int because we are only parsing up to 9 digits
let pos = position;
while (pos < maxEndPos) {
const ch = text.charAt(pos++);
const digit = context.symbols().convertToDigit(ch);
if (digit < 0) {
if (pos < minEndPos) {
return ~position; // need at least min width digits
}
pos--;
break;
}
total = total * 10 + digit;
}
const moveLeft = pos - position;
const scale = Math.pow(10, moveLeft);
const value = this.convertFromFraction(total, scale);
return context.setParsedField(this.field, value, position, pos);
}
/**
*
* @param {Number} value the value to convert, must be valid for this rule
* @param {String} zeroDigit the character for zero
* @return {String} the value as a fraction within the range, from 0 to 1, not null
*/
convertToFraction(value, zeroDigit) {
const range = this.field.range();
range.checkValidValue(value, this.field);
const _min = range.minimum();
const _range = range.maximum() - _min + 1;
const _value = value - _min;
const _scaled = MathUtil.intDiv((_value * 1000000000), _range);
let fraction = `${_scaled}`;
while(fraction.length < 9){
fraction = zeroDigit + fraction;
}
return fraction;
}
/**
*
* @param {Number} total the fraction to convert, not null
* @param {Number} scale the scale, not null
* @return {Number} the value of the field, valid for this rule
* @throws DateTimeException if the value cannot be converted
*/
convertFromFraction(total, scale) {
const range = this.field.range();
const _min = range.minimum();
const _range = range.maximum() - _min + 1;
const _value = MathUtil.intDiv((total * _range), scale);
return _value;
}
toString() {
const decimal = (this.decimalPoint ? ',DecimalPoint' : '');
return `Fraction(${this.field},${this.minWidth},${this.maxWidth}${decimal})`;
}
}

View File

@@ -0,0 +1,367 @@
/**
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
import { assert } from '../../assert';
import { ArithmeticException, DateTimeException, IllegalArgumentException } from '../../errors';
import { MathUtil } from '../../MathUtil';
import { IsoChronology } from '../../chrono/IsoChronology';
import { SignStyle } from '../SignStyle';
const MAX_WIDTH = 15; // can't parse all numbers with more then 15 digits in javascript
const EXCEED_POINTS = [
0,
10,
100,
1000,
10000,
100000,
1000000,
10000000,
100000000,
1000000000
];
/**
* @private
*/
export class NumberPrinterParser {
/**
* Constructor.
*
* @param field the field to print, not null
* @param minWidth the minimum field width, from 1 to 19
* @param maxWidth the maximum field width, from minWidth to 19
* @param signStyle the positive/negative sign style, not null
* @param subsequentWidth the width of subsequent non-negative numbers, 0 or greater,
* -1 if fixed width due to active adjacent parsing
*/
constructor(field, minWidth, maxWidth, signStyle, subsequentWidth=0){
this._field = field;
this._minWidth = minWidth;
this._maxWidth = maxWidth;
this._signStyle = signStyle;
this._subsequentWidth = subsequentWidth;
}
field(){ return this._field;}
minWidth(){ return this._minWidth;}
maxWidth(){ return this._maxWidth;}
signStyle(){ return this._signStyle;}
withFixedWidth() {
if (this._subsequentWidth === -1) {
return this;
}
return new NumberPrinterParser(this._field, this._minWidth, this._maxWidth, this._signStyle, -1);
}
withSubsequentWidth(subsequentWidth) {
return new NumberPrinterParser(this._field, this._minWidth, this._maxWidth, this._signStyle, this._subsequentWidth + subsequentWidth);
}
_isFixedWidth() {
return this._subsequentWidth === -1 ||
(this._subsequentWidth > 0 && this._minWidth === this._maxWidth && this._signStyle === SignStyle.NOT_NEGATIVE);
}
print(context, buf) {
const contextValue = context.getValue(this._field);
if (contextValue == null) {
return false;
}
const value = this._getValue(context, contextValue);
const symbols = context.symbols();
let str = `${Math.abs(value)}`;
if (str.length > this._maxWidth) {
throw new DateTimeException(`Field ${this._field
} cannot be printed as the value ${value
} exceeds the maximum print width of ${this._maxWidth}`);
}
str = symbols.convertNumberToI18N(str);
if (value >= 0) {
switch (this._signStyle) {
case SignStyle.EXCEEDS_PAD:
if (this._minWidth < MAX_WIDTH && value >= EXCEED_POINTS[this._minWidth]) {
buf.append(symbols.positiveSign());
}
break;
case SignStyle.ALWAYS:
buf.append(symbols.positiveSign());
break;
}
} else {
switch (this._signStyle) {
case SignStyle.NORMAL:
case SignStyle.EXCEEDS_PAD:
case SignStyle.ALWAYS:
buf.append(symbols.negativeSign());
break;
case SignStyle.NOT_NEGATIVE:
throw new DateTimeException(`Field ${this._field
} cannot be printed as the value ${value
} cannot be negative according to the SignStyle`);
}
}
for (let i = 0; i < this._minWidth - str.length; i++) {
buf.append(symbols.zeroDigit());
}
buf.append(str);
return true;
}
parse(context, text, position){
const length = text.length;
if (position === length) {
return ~position;
}
assert(position>=0 && position<length);
const sign = text.charAt(position); // IOOBE if invalid position
let negative = false;
let positive = false;
if (sign === context.symbols().positiveSign()) {
if (this._signStyle.parse(true, context.isStrict(), this._minWidth === this._maxWidth) === false) {
return ~position;
}
positive = true;
position++;
} else if (sign === context.symbols().negativeSign()) {
if (this._signStyle.parse(false, context.isStrict(), this._minWidth === this._maxWidth) === false) {
return ~position;
}
negative = true;
position++;
} else {
if (this._signStyle === SignStyle.ALWAYS && context.isStrict()) {
return ~position;
}
}
const effMinWidth = (context.isStrict() || this._isFixedWidth() ? this._minWidth : 1);
const minEndPos = position + effMinWidth;
if (minEndPos > length) {
return ~position;
}
let effMaxWidth = (context.isStrict() || this._isFixedWidth() ? this._maxWidth : 9) + Math.max(this._subsequentWidth, 0);
let total = 0;
let pos = position;
for (let pass = 0; pass < 2; pass++) {
const maxEndPos = Math.min(pos + effMaxWidth, length);
while (pos < maxEndPos) {
const ch = text.charAt(pos++);
const digit = context.symbols().convertToDigit(ch);
if (digit < 0) {
pos--;
if (pos < minEndPos) {
return ~position; // need at least min width digits
}
break;
}
if ((pos - position) > MAX_WIDTH) {
throw new ArithmeticException('number text exceeds length');
} else {
total = total * 10 + digit;
}
}
if (this._subsequentWidth > 0 && pass === 0) {
// re-parse now we know the correct width
const parseLen = pos - position;
effMaxWidth = Math.max(effMinWidth, parseLen - this._subsequentWidth);
pos = position;
total = 0;
} else {
break;
}
}
if (negative) {
if (total === 0 && context.isStrict()) {
return ~(position - 1); // minus zero not allowed
}
if(total !== 0) {
total = -total;
}
} else if (this._signStyle === SignStyle.EXCEEDS_PAD && context.isStrict()) {
const parseLen = pos - position;
if (positive) {
if (parseLen <= this._minWidth) {
return ~(position - 1); // '+' only parsed if minWidth exceeded
}
} else {
if (parseLen > this._minWidth) {
return ~position; // '+' must be parsed if minWidth exceeded
}
}
}
return this._setValue(context, total, position, pos);
}
/**
* Gets the value to output.
* (This is needed to allow e.g. ReducedPrinterParser to override this and change the value!
*
* @param context the context
* @param value the value of the field, not null
* @return the value
* @private
*/
_getValue(context, value) {
return value;
}
/**
* Stores the value.
*
* @param context the context to store into, not null
* @param value the value
* @param errorPos the position of the field being parsed
* @param successPos the position after the field being parsed
* @return the new position
*/
_setValue(context, value, errorPos, successPos) {
return context.setParsedField(this._field, value, errorPos, successPos);
}
toString() {
if (this._minWidth === 1 && this._maxWidth === MAX_WIDTH && this._signStyle === SignStyle.NORMAL) {
return `Value(${this._field})`;
}
if (this._minWidth === this._maxWidth && this._signStyle === SignStyle.NOT_NEGATIVE) {
return `Value(${this._field},${this._minWidth})`;
}
return `Value(${this._field},${this._minWidth},${this._maxWidth},${this._signStyle})`;
}
}
//-----------------------------------------------------------------------
/**
* Prints and parses a reduced numeric date-time field.
* @private
*/
export class ReducedPrinterParser extends NumberPrinterParser {
/**
* Constructor.
*
* @param {TemporalField} field the field to print, validated not null
* @param {number} width the field width, from 1 to 10
* @param {number} maxWidth the field max width, from 1 to 10
* @param {number} baseValue the base value
* @param {ChronoLocalDate} baseDate the base date
*/
constructor(field, width, maxWidth, baseValue, baseDate) {
super(field, width, maxWidth, SignStyle.NOT_NEGATIVE);
if (width < 1 || width > 10) {
throw new IllegalArgumentException(`The width must be from 1 to 10 inclusive but was ${width}`);
}
if (maxWidth < 1 || maxWidth > 10) {
throw new IllegalArgumentException(`The maxWidth must be from 1 to 10 inclusive but was ${maxWidth}`);
}
if (maxWidth < width) {
throw new IllegalArgumentException('The maxWidth must be greater than the width');
}
if (baseDate === null) {
if (field.range().isValidValue(baseValue) === false) {
throw new IllegalArgumentException('The base value must be within the range of the field');
}
if ((baseValue + EXCEED_POINTS[width]) > MathUtil.MAX_SAFE_INTEGER) {
throw new DateTimeException('Unable to add printer-parser as the range exceeds the capacity of an int');
}
}
this._baseValue = baseValue;
this._baseDate = baseDate;
}
/**
*
* @param {DateTimePrintContext} context
* @param {number} value
*/
_getValue(context, value) {
const absValue = Math.abs(value);
let baseValue = this._baseValue;
if (this._baseDate !== null) {
// TODO: in threetenbp the following line is used, but we dont have Chronology yet,
// let chrono = Chronology.from(context.getTemporal());
// so let's use IsoChronology for now
context.temporal();
const chrono = IsoChronology.INSTANCE;
baseValue = chrono.date(this._baseDate).get(this._field);
}
if (value >= baseValue && value < baseValue + EXCEED_POINTS[this._minWidth]) {
return absValue % EXCEED_POINTS[this._minWidth];
}
return absValue % EXCEED_POINTS[this._maxWidth];
}
/**
*
* @param {DateTimeParseContext} context
* @param {number} value
* @param {number} errorPos
* @param {number} successPos
*/
_setValue(context, value, errorPos, successPos) {
let baseValue = this._baseValue;
if (this._baseDate != null) {
const chrono = context.getEffectiveChronology();
baseValue = chrono.date(this._baseDate).get(this._field);
// TODO: not implemented??
// context.addChronologyChangedParser(this, value, errorPos, successPos);
}
const parseLen = successPos - errorPos;
if (parseLen === this._minWidth && value >= 0) {
const range = EXCEED_POINTS[this._minWidth];
const lastPart = baseValue % range;
const basePart = baseValue - lastPart;
if (baseValue > 0) {
value = basePart + value;
} else {
value = basePart - value;
}
if (value < baseValue) {
value += range;
}
}
return context.setParsedField(this._field, value, errorPos, successPos);
}
withFixedWidth() {
if (this._subsequentWidth === -1) {
return this;
}
return new ReducedPrinterParser(this._field, this._minWidth, this._maxWidth, this._baseValue, this._baseDate, -1);
}
/**
*
* @param {number} subsequentWidth
* @returns {ReducedPrinterParser}
*/
withSubsequentWidth(subsequentWidth) {
return new ReducedPrinterParser(this._field, this._minWidth, this._maxWidth, this._baseValue, this._baseDate,
this._subsequentWidth + subsequentWidth);
}
/**
*
* @param {DateTimeParseContext} context
*/
isFixedWidth(context) {
if (context.isStrict() === false) {
return false;
}
return super.isFixedWidth(context);
}
toString() {
return `ReducedValue(${this._field},${this._minWidth},${this._maxWidth},${this._baseDate != null ? this._baseDate : this._baseValue})`;
}
}

View File

@@ -0,0 +1,177 @@
/**
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
import { requireNonNull } from '../../assert';
import { IllegalArgumentException } from '../../errors';
import { MathUtil } from '../../MathUtil';
import { ChronoField } from '../../temporal/ChronoField';
//-----------------------------------------------------------------------
const PATTERNS = [
'+HH', '+HHmm', '+HH:mm', '+HHMM', '+HH:MM', '+HHMMss', '+HH:MM:ss', '+HHMMSS', '+HH:MM:SS'
];
/**
* Prints or parses an offset ID.
* @private
*/
export class OffsetIdPrinterParser {
/**
* Constructor.
*
* @param {string} noOffsetText the text to use for UTC, not null
* @param {string} pattern the pattern
*/
constructor(noOffsetText, pattern) {
requireNonNull(noOffsetText, 'noOffsetText');
requireNonNull(pattern, 'pattern');
this.noOffsetText = noOffsetText;
this.type = this._checkPattern(pattern);
}
/**
* @param {String} pattern
* @return {number}
*/
_checkPattern(pattern) {
for (let i = 0; i < PATTERNS.length; i++) {
if (PATTERNS[i] === pattern) {
return i;
}
}
throw new IllegalArgumentException(`Invalid zone offset pattern: ${pattern}`);
}
/**
* @param {DateTimePrintContext} context
* @param {StringBuilder} buf
* @return {boolean}
*/
print(context, buf) {
const offsetSecs = context.getValue(ChronoField.OFFSET_SECONDS);
if (offsetSecs == null) {
return false;
}
const totalSecs = MathUtil.safeToInt(offsetSecs);
if (totalSecs === 0) {
buf.append(this.noOffsetText);
} else {
const absHours = Math.abs(MathUtil.intMod(MathUtil.intDiv(totalSecs, 3600), 100)); // anything larger than 99 silently dropped
const absMinutes = Math.abs(MathUtil.intMod(MathUtil.intDiv(totalSecs, 60), 60));
const absSeconds = Math.abs(MathUtil.intMod(totalSecs, 60));
const bufPos = buf.length();
let output = absHours;
buf.append(totalSecs < 0 ? '-' : '+')
.appendChar((`${MathUtil.intDiv(absHours, 10)}0`)).appendChar(`${MathUtil.intMod(absHours, 10)}0`);
if (this.type >= 3 || (this.type >= 1 && absMinutes > 0)) {
buf.append((this.type % 2) === 0 ? ':' : '')
.appendChar((`${MathUtil.intDiv(absMinutes, 10)}0`)).appendChar((`${absMinutes % 10}0`));
output += absMinutes;
if (this.type >= 7 || (this.type >= 5 && absSeconds > 0)) {
buf.append((this.type % 2) === 0 ? ':' : '')
.appendChar((`${MathUtil.intDiv(absSeconds, 10)}0`)).appendChar((`${absSeconds % 10}0`));
output += absSeconds;
}
}
if (output === 0) {
buf.setLength(bufPos);
buf.append(this.noOffsetText);
}
}
return true;
}
/**
* @param {DateTimeParseContext} context
* @param {String} text
* @param {number} position
* @return {number}
*/
parse(context, text, position) {
const length = text.length;
const noOffsetLen = this.noOffsetText.length;
if (noOffsetLen === 0) {
if (position === length) {
return context.setParsedField(ChronoField.OFFSET_SECONDS, 0, position, position);
}
} else {
if (position === length) {
return ~position;
}
if (context.subSequenceEquals(text, position, this.noOffsetText, 0, noOffsetLen)) {
return context.setParsedField(ChronoField.OFFSET_SECONDS, 0, position, position + noOffsetLen);
}
}
// parse normal plus/minus offset
const sign = text[position]; // IOOBE if invalid position
if (sign === '+' || sign === '-') {
// starts
const negative = (sign === '-' ? -1 : 1);
const array = [0,0,0,0];
array[0] = position + 1;
if ((this._parseNumber(array, 1, text, true) ||
this._parseNumber(array, 2, text, this.type >=3) ||
this._parseNumber(array, 3, text, false)) === false) {
// success
const offsetSecs = MathUtil.safeZero(negative * (array[1] * 3600 + array[2] * 60 + array[3]));
return context.setParsedField(ChronoField.OFFSET_SECONDS, offsetSecs, position, array[0]);
}
}
// handle special case of empty no offset text
if (noOffsetLen === 0) {
return context.setParsedField(ChronoField.OFFSET_SECONDS, 0, position, position + noOffsetLen);
}
return ~position;
}
/**
* Parse a two digit zero-prefixed number.
*
* @param {number[]} array the array of parsed data, 0=pos,1=hours,2=mins,3=secs, not null
* @param {number} arrayIndex the index to parse the value into
* @param {string} parseText the offset ID, not null
* @param {boolean} required whether this number is required
* @return {boolean} true if an error occurred
*/
_parseNumber(array, arrayIndex, parseText, required) {
if ((this.type + 3) / 2 < arrayIndex) {
return false; // ignore seconds/minutes
}
let pos = array[0];
if ((this.type % 2) === 0 && arrayIndex > 1) {
if (pos + 1 > parseText.length || parseText[pos] !== ':') {
return required;
}
pos++;
}
if (pos + 2 > parseText.length) {
return required;
}
const ch1 = parseText[pos++];
const ch2 = parseText[pos++];
if (ch1 < '0' || ch1 > '9' || ch2 < '0' || ch2 > '9') {
return required;
}
const value = (ch1.charCodeAt(0) - 48) * 10 + (ch2.charCodeAt(0) - 48);
if (value < 0 || value > 59) {
return required;
}
array[arrayIndex] = value;
array[0] = pos;
return false;
}
toString() {
const converted = this.noOffsetText.replace('\'', '\'\'');
return `Offset(${PATTERNS[this.type]},'${converted}')`;
}
}
OffsetIdPrinterParser.INSTANCE_ID = new OffsetIdPrinterParser('Z', '+HH:MM:ss');
OffsetIdPrinterParser.PATTERNS = PATTERNS;

View File

@@ -0,0 +1,81 @@
/**
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
import { assert } from '../../assert';
import { DateTimeException } from '../../errors';
/**
* Pads the output to a fixed width.
* @private
*/
export class PadPrinterParserDecorator {
/**
* Constructor.
*
* @param printerParser the printer, not null
* @param padWidth the width to pad to, 1 or greater
* @param padChar the pad character
*/
constructor(printerParser, padWidth, padChar) {
// input checked by DateTimeFormatterBuilder
this._printerParser = printerParser;
this._padWidth = padWidth;
this._padChar = padChar;
}
print(context, buf) {
const preLen = buf.length();
if (this._printerParser.print(context, buf) === false) {
return false;
}
const len = buf.length() - preLen;
if (len > this._padWidth) {
throw new DateTimeException(
`Cannot print as output of ${len} characters exceeds pad width of ${this._padWidth}`);
}
for (let i = 0; i < this._padWidth - len; i++) {
buf.insert(preLen, this._padChar);
}
return true;
}
parse(context, text, position) {
// cache context before changed by decorated parser
const strict = context.isStrict();
const caseSensitive = context.isCaseSensitive();
// parse
assert(!(position > text.length));
assert(position >= 0);
if (position === text.length) {
return ~position; // no more characters in the string
}
let endPos = position + this._padWidth;
if (endPos > text.length) {
if (strict) {
return ~position; // not enough characters in the string to meet the parse width
}
endPos = text.length;
}
let pos = position;
while (pos < endPos &&
(caseSensitive ? text[pos] === this._padChar : context.charEquals(text[pos], this._padChar))) {
pos++;
}
text = text.substring(0, endPos);
const resultPos = this._printerParser.parse(context, text, pos);
if (resultPos !== endPos && strict) {
return ~(position + pos); // parse of decorated field didn't parse to the end
}
return resultPos;
}
toString() {
return `Pad(${this._printerParser},${this._padWidth}${(this._padChar === ' ' ? ')' : `,'${this._padChar}')`)}`;
}
}

View File

@@ -0,0 +1,44 @@
/**
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
import { Enum } from '../../Enum';
/**
* @private
*/
export class SettingsParser extends Enum {
print(/*context, buf*/) {
return true; // nothing to do here
}
parse(context, text, position) {
// using ordinals to avoid javac synthetic inner class
switch (this) {
case SettingsParser.SENSITIVE: context.setCaseSensitive(true); break;
case SettingsParser.INSENSITIVE: context.setCaseSensitive(false); break;
case SettingsParser.STRICT: context.setStrict(true); break;
case SettingsParser.LENIENT: context.setStrict(false); break;
}
return position;
}
toString() {
// using ordinals to avoid javac synthetic inner class
switch (this) {
case SettingsParser.SENSITIVE: return 'ParseCaseSensitive(true)';
case SettingsParser.INSENSITIVE: return 'ParseCaseSensitive(false)';
case SettingsParser.STRICT: return 'ParseStrict(true)';
case SettingsParser.LENIENT: return 'ParseStrict(false)';
}
}
}
SettingsParser.SENSITIVE = new SettingsParser('SENSITIVE');
SettingsParser.INSENSITIVE = new SettingsParser('INSENSITIVE');
SettingsParser.STRICT = new SettingsParser('STRICT');
SettingsParser.LENIENT = new SettingsParser('LENIENT');

View File

@@ -0,0 +1,39 @@
/**
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
import { assert } from '../../assert';
/**
* Prints or parses a string literal.
* @private
*/
export class StringLiteralPrinterParser {
constructor(literal) {
this._literal = literal;
}
print(context, buf) {
buf.append(this._literal);
return true;
}
parse(context, text, position) {
const length = text.length;
assert(!(position > length || position < 0));
if (context.subSequenceEquals(text, position, this._literal, 0, this._literal.length) === false) {
return ~position;
}
return position + this._literal.length;
}
toString() {
const converted = this._literal.replace("'", "''");
return `'${converted}'`;
}
}

View File

@@ -0,0 +1,218 @@
/**
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
import { ZoneOffset } from '../../ZoneOffset';
import { ZoneId } from '../../ZoneId';
import { ZoneRegion } from '../../ZoneRegion';
import { ChronoField } from '../../temporal/ChronoField';
import { ZoneRulesProvider } from '../../zone/ZoneRulesProvider';
import { OffsetIdPrinterParser } from './OffsetIdPrinterParser';
/**
* Prints or parses a zone ID.
* @private
*/
export class ZoneIdPrinterParser {
/**
*
* @param {TemporalQuery} query
* @param {string} description
*/
constructor(query, description) {
this.query = query;
this.description = description;
}
//-----------------------------------------------------------------------
/**
*
* @param {DateTimePrintContext } context
* @param {StringBuilder} buf
* @returns {boolean}
*/
print(context, buf) {
const zone = context.getValueQuery(this.query);
if (zone == null) {
return false;
}
buf.append(zone.id());
return true;
}
//-----------------------------------------------------------------------
/**
* This implementation looks for the longest matching string.
* For example, parsing Etc/GMT-2 will return Etc/GMC-2 rather than just
* Etc/GMC although both are valid.
*
* This implementation uses a tree to search for valid time-zone names in
* the parseText. The top level node of the tree has a length equal to the
* length of the shortest time-zone as well as the beginning characters of
* all other time-zones.
*
* @param {DateTimeParseContext} context
* @param {String} text
* @param {number} position
* @return {number}
*/
parse(context, text, position) {
const length = text.length;
if (position > length) {
return ~position;
}
if (position === length) {
return ~position;
}
// handle fixed time-zone IDs
const nextChar = text.charAt(position);
if (nextChar === '+' || nextChar === '-') {
const newContext = context.copy();
const endPos = OffsetIdPrinterParser.INSTANCE_ID.parse(newContext, text, position);
if (endPos < 0) {
return endPos;
}
const offset = newContext.getParsed(ChronoField.OFFSET_SECONDS);
const zone = ZoneOffset.ofTotalSeconds(offset);
context.setParsedZone(zone);
return endPos;
} else if (length >= position + 2) {
const nextNextChar = text.charAt(position + 1);
if (context.charEquals(nextChar, 'U') &&
context.charEquals(nextNextChar, 'T')) {
if (length >= position + 3 &&
context.charEquals(text.charAt(position + 2), 'C')) {
return this._parsePrefixedOffset(context, text, position, position + 3);
}
return this._parsePrefixedOffset(context, text, position, position + 2);
} else if (context.charEquals(nextChar, 'G') &&
length >= position + 3 &&
context.charEquals(nextNextChar, 'M') &&
context.charEquals(text.charAt(position + 2), 'T')) {
return this._parsePrefixedOffset(context, text, position, position + 3);
}
}
// javascript special case
if(text.substr(position, 6) === 'SYSTEM'){
context.setParsedZone(ZoneId.systemDefault());
return position + 6;
}
// ...
if (context.charEquals(nextChar, 'Z')) {
context.setParsedZone(ZoneOffset.UTC);
return position + 1;
}
const availableZoneIds = ZoneRulesProvider.getAvailableZoneIds();
if (zoneIdTree.size !== availableZoneIds.length) {
zoneIdTree = ZoneIdTree.createTreeMap(availableZoneIds);
}
const maxParseLength = length - position;
let treeMap = zoneIdTree.treeMap;
let parsedZoneId = null;
let parseLength = 0;
while(treeMap != null) {
const parsedSubZoneId = text.substr(position, Math.min(treeMap.length, maxParseLength));
treeMap = treeMap.get(parsedSubZoneId);
if (treeMap != null && treeMap.isLeaf) {
parsedZoneId = parsedSubZoneId;
parseLength = treeMap.length;
}
}
if (parsedZoneId != null) {
context.setParsedZone(ZoneRegion.ofId(parsedZoneId));
return position + parseLength;
}
return ~position;
}
/**
*
* @param {DateTimeParseContext} context
* @param {String} text
* @param {number} prefixPos
* @param {number} position
* @return {number}
*/
_parsePrefixedOffset(context, text, prefixPos, position) {
const prefix = text.substring(prefixPos, position).toUpperCase();
const newContext = context.copy();
if (position < text.length && context.charEquals(text.charAt(position), 'Z')) {
context.setParsedZone(ZoneId.ofOffset(prefix, ZoneOffset.UTC));
return position;
}
const endPos = OffsetIdPrinterParser.INSTANCE_ID.parse(newContext, text, position);
if (endPos < 0) {
context.setParsedZone(ZoneId.ofOffset(prefix, ZoneOffset.UTC));
return position;
}
const offsetSecs = newContext.getParsed(ChronoField.OFFSET_SECONDS);
const offset = ZoneOffset.ofTotalSeconds(offsetSecs);
context.setParsedZone(ZoneId.ofOffset(prefix, offset));
return endPos;
}
/**
*
* @returns {string}
*/
toString() {
return this.description;
}
}
class ZoneIdTree {
static createTreeMap(availableZoneIds) {
const sortedZoneIds = availableZoneIds.sort((a, b) => a.length - b.length);
const treeMap = new ZoneIdTreeMap(sortedZoneIds[0].length, false);
for (let i=0; i<sortedZoneIds.length; i++){
treeMap.add(sortedZoneIds[i]);
}
return new ZoneIdTree(sortedZoneIds.length, treeMap);
}
constructor(size, treeMap) {
this.size = size;
this.treeMap = treeMap;
}
}
class ZoneIdTreeMap {
constructor(length = 0, isLeaf = false){
this.length = length;
this.isLeaf = isLeaf;
this._treeMap = {};
}
add(zoneId){
const idLength = zoneId.length;
if(idLength === this.length) {
this._treeMap[zoneId] = new ZoneIdTreeMap(idLength, true);
} else if (idLength > this.length) {
const subZoneId = zoneId.substr(0, this.length);
let subTreeMap = this._treeMap[subZoneId];
if (subTreeMap == null) {
subTreeMap = new ZoneIdTreeMap(idLength, false);
this._treeMap[subZoneId] = subTreeMap;
}
subTreeMap.add(zoneId);
}
}
get(zoneId){
return this._treeMap[zoneId];
}
}
let zoneIdTree = new ZoneIdTree([]);

218
node_modules/@js-joda/core/src/js-joda.js generated vendored Normal file
View File

@@ -0,0 +1,218 @@
/**
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
import {
ArithmeticException,
DateTimeException,
DateTimeParseException,
IllegalArgumentException,
IllegalStateException,
UnsupportedTemporalTypeException,
NullPointerException
} from './errors';
import { Clock } from './Clock';
import { DayOfWeek } from './DayOfWeek';
import { Duration } from './Duration';
import { Instant } from './Instant';
import { LocalDate } from './LocalDate';
import { LocalTime } from './LocalTime';
import { LocalDateTime } from './LocalDateTime';
import { Month } from './Month';
import { MonthDay } from './MonthDay';
import { OffsetDateTime } from './OffsetDateTime';
import { OffsetTime } from './OffsetTime';
import { Period } from './Period';
import { Year } from './Year';
import { YearConstants } from './YearConstants';
import { YearMonth } from './YearMonth';
import { ZonedDateTime } from './ZonedDateTime';
import { ZoneOffset } from './ZoneOffset';
import { ZoneId } from './ZoneId';
import { ZoneRegion } from './ZoneRegion';
import { ZoneOffsetTransition } from './zone/ZoneOffsetTransition';
import { ZoneRules } from './zone/ZoneRules';
import { ZoneRulesProvider } from './zone/ZoneRulesProvider';
import { ChronoLocalDate } from './chrono/ChronoLocalDate';
import { ChronoLocalDateTime } from './chrono/ChronoLocalDateTime';
import { ChronoZonedDateTime } from './chrono/ChronoZonedDateTime';
import { IsoChronology } from './chrono/IsoChronology';
import { ChronoField } from './temporal/ChronoField';
import { ChronoUnit } from './temporal/ChronoUnit';
import { IsoFields } from './temporal/IsoFields';
import { Temporal } from './temporal/Temporal';
import { TemporalAccessor } from './temporal/TemporalAccessor';
import { TemporalAdjuster } from './temporal/TemporalAdjuster';
import { TemporalAdjusters } from './temporal/TemporalAdjusters';
import { TemporalAmount } from './temporal/TemporalAmount';
import { TemporalField } from './temporal/TemporalField';
import { TemporalQueries } from './temporal/TemporalQueries';
import { TemporalQuery } from './temporal/TemporalQuery';
import { TemporalUnit } from './temporal/TemporalUnit';
import { ValueRange } from './temporal/ValueRange';
import { DateTimeFormatter } from './format/DateTimeFormatter';
import { DateTimeFormatterBuilder } from './format/DateTimeFormatterBuilder';
import { DecimalStyle } from './format/DecimalStyle';
import { ParsePosition } from './format/ParsePosition';
import { ResolverStyle } from './format/ResolverStyle';
import { SignStyle } from './format/SignStyle';
import { TextStyle } from './format/TextStyle';
// init static properties
import './_init';
// private/internal exports, e.g. for use in plugins
import { MathUtil } from './MathUtil';
import { StringUtil } from './StringUtil';
import { DateTimeBuilder } from './format/DateTimeBuilder';
import { DateTimeParseContext } from './format/DateTimeParseContext';
import { DateTimePrintContext } from './format/DateTimePrintContext';
import { StringBuilder } from './format/StringBuilder';
import * as assert from './assert';
import { convert } from './convert';
import { nativeJs } from './nativeJs';
import { bindUse } from './use';
const _ = {
assert,
DateTimeBuilder,
DateTimeParseContext,
DateTimePrintContext,
MathUtil,
StringUtil,
StringBuilder,
};
const jsJodaExports = {
_,
convert,
nativeJs,
ArithmeticException,
DateTimeException,
DateTimeParseException,
IllegalArgumentException,
IllegalStateException,
UnsupportedTemporalTypeException,
NullPointerException,
Clock,
DayOfWeek,
Duration,
Instant,
LocalDate,
LocalTime,
LocalDateTime,
OffsetTime,
OffsetDateTime,
Month,
MonthDay,
ParsePosition,
Period,
Year,
YearConstants,
YearMonth,
ZonedDateTime,
ZoneOffset,
ZoneId,
ZoneRegion,
ZoneOffsetTransition,
ZoneRules,
ZoneRulesProvider,
ChronoLocalDate,
ChronoLocalDateTime,
ChronoZonedDateTime,
IsoChronology,
ChronoField,
ChronoUnit,
IsoFields,
Temporal,
TemporalAccessor,
TemporalAdjuster,
TemporalAdjusters,
TemporalAmount,
TemporalField,
TemporalQueries,
TemporalQuery,
TemporalUnit,
ValueRange,
DateTimeFormatter,
DateTimeFormatterBuilder,
DecimalStyle,
ResolverStyle,
SignStyle,
TextStyle,
};
/**
* @private
*
* @type { function(function(jsJoda: JsJoda) }
*/
const use = bindUse(jsJodaExports);
jsJodaExports.use = use;
export {
_,
use,
convert,
nativeJs,
ArithmeticException,
DateTimeException,
DateTimeParseException,
IllegalArgumentException,
IllegalStateException,
UnsupportedTemporalTypeException,
NullPointerException,
Clock,
DayOfWeek,
Duration,
Instant,
LocalDate,
LocalTime,
LocalDateTime,
Month,
MonthDay,
OffsetTime,
OffsetDateTime,
Period,
ParsePosition,
Year,
YearConstants,
YearMonth,
ZonedDateTime,
ZoneOffset,
ZoneId,
ZoneRegion,
ZoneOffsetTransition,
ZoneRules,
ZoneRulesProvider,
ChronoLocalDate,
ChronoLocalDateTime,
ChronoZonedDateTime,
IsoChronology,
ChronoField,
ChronoUnit,
IsoFields,
Temporal,
TemporalAccessor,
TemporalAdjuster,
TemporalAdjusters,
TemporalAmount,
TemporalField,
TemporalQueries,
TemporalQuery,
TemporalUnit,
ValueRange,
DateTimeFormatter,
DateTimeFormatterBuilder,
DecimalStyle,
ResolverStyle,
SignStyle,
TextStyle,
};

25
node_modules/@js-joda/core/src/nativeJs.js generated vendored Normal file
View File

@@ -0,0 +1,25 @@
/*
* @copyright (c) 2015-present, Philipp Thürwächter, Pattrick Hüper & js-joda contributors
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
import { requireNonNull } from './assert';
import { IllegalArgumentException } from './errors';
import { Instant, ZoneId } from './js-joda';
/**
* Creates ZonedDateTime from a javascript Date or a moment instance.
* @param {!(Date|moment)} date - a javascript Date or a moment instance
* @param {ZoneId} [zone = ZoneId.systemDefault()] - the zone of the returned ZonedDateTime, defaults to ZoneId.systemDefault()
* @returns {ZonedDateTime}
*/
export function nativeJs(date, zone = ZoneId.systemDefault()) {
requireNonNull(date, 'date');
requireNonNull(zone, 'zone');
if(date instanceof Date) {
return Instant.ofEpochMilli(date.getTime()).atZone(zone);
} else if(typeof date.toDate === 'function' && date.toDate() instanceof Date) {
return Instant.ofEpochMilli(date.toDate().getTime()).atZone(zone);
}
throw new IllegalArgumentException('date must be a javascript Date or a moment instance');
}

470
node_modules/@js-joda/core/src/temporal/ChronoField.js generated vendored Normal file
View File

@@ -0,0 +1,470 @@
/**
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
import { MAX_SAFE_INTEGER, MIN_SAFE_INTEGER } from '../MathUtil';
import { ChronoUnit } from './ChronoUnit';
import { TemporalField } from './TemporalField';
import { ValueRange } from './ValueRange';
import { YearConstants } from '../YearConstants';
/**
* A standard set of fields.
*
* This set of fields provide field-based access to manipulate a date, time or date-time.
* The standard set of fields can be extended by implementing {@link TemporalField}.
*
* These fields are intended to be applicable in multiple calendar systems.
* For example, most non-ISO calendar systems define dates as a year, month and day,
* just with slightly different rules.
* The documentation of each field explains how it operates.
*
* ### Static properties:
*
* - `ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH`: This represents concept of the count of
* days within the period of a week where the weeks are aligned to the start of the month.
* This field is typically used with `ALIGNED_WEEK_OF_MONTH`.
*
* - `ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR`: This represents concept of the count of days
* within the period of a week where the weeks are aligned to the start of the year.
* This field is typically used with `ALIGNED_WEEK_OF_YEAR`.
*
* - `ChronoField.ALIGNED_WEEK_OF_MONTH`: This represents concept of the count of weeks within
* the period of a month where the weeks are aligned to the start of the month. This field
* is typically used with `ALIGNED_DAY_OF_WEEK_IN_MONTH`.
*
* - `ChronoField.ALIGNED_WEEK_OF_YEAR`: This represents concept of the count of weeks within
* the period of a year where the weeks are aligned to the start of the year. This field
* is typically used with `ALIGNED_DAY_OF_WEEK_IN_YEAR`.
*
* - `ChronoField.AMPM_OF_DAY`: This counts the AM/PM within the day, from 0 (AM) to 1 (PM).
*
* - `ChronoField.CLOCK_HOUR_OF_AMPM`: This counts the hour within the AM/PM, from 1 to 12.
* This is the hour that would be observed on a standard 12-hour analog wall clock.
*
* - `ChronoField.CLOCK_HOUR_OF_DAY`: This counts the hour within the AM/PM, from 1 to 24.
* This is the hour that would be observed on a 24-hour analog wall clock.
*
* - `ChronoField.DAY_OF_MONTH`: This represents the concept of the day within the month.
* In the default ISO calendar system, this has values from 1 to 31 in most months.
* April, June, September, November have days from 1 to 30, while February has days from
* 1 to 28, or 29 in a leap year.
*
* - `ChronoField.DAY_OF_WEEK`: This represents the standard concept of the day of the week.
* In the default ISO calendar system, this has values from Monday (1) to Sunday (7).
* The {@link DayOfWeek} class can be used to interpret the result.
*
* - `ChronoField.DAY_OF_YEAR`: This represents the concept of the day within the year.
* In the default ISO calendar system, this has values from 1 to 365 in standard years and
* 1 to 366 in leap years.
*
* - `ChronoField.EPOCH_DAY`: This field is the sequential count of days where
* 1970-01-01 (ISO) is zero. Note that this uses the local time-line, ignoring offset and
* time-zone.
*
* - `ChronoField.ERA`: This represents the concept of the era, which is the largest
* division of the time-line. This field is typically used with `YEAR_OF_ERA`.
*
* In the default ISO calendar system, there are two eras defined, 'BCE' and 'CE'. The era
* 'CE' is the one currently in use and year-of-era runs from 1 to the maximum value.
* The era 'BCE' is the previous era, and the year-of-era runs backwards.
*
* - `ChronoField.HOUR_OF_AMPM`: This counts the hour within the AM/PM, from 0 to 11.
* This is the hour that would be observed on a standard 12-hour digital clock.
*
* - `ChronoField.HOUR_OF_DAY`: This counts the hour within the day, from 0 to 23. This is
* the hour that would be observed on a standard 24-hour digital clock.
*
* - `ChronoField.INSTANT_SECONDS`: This represents the concept of the sequential count of
* seconds where 1970-01-01T00:00Z (ISO) is zero. This field may be used with `NANO_OF_DAY`
* to represent the fraction of the day.
*
* An Instant represents an instantaneous point on the time-line. On their own they have
* no elements which allow a local date-time to be obtained. Only when paired with an offset
* or time-zone can the local date or time be found. This field allows the seconds part of
* the instant to be queried.
*
* - `ChronoField.MICRO_OF_DAY`: This counts the microsecond within the day, from 0 to
* (24 * 60 * 60 * 1,000,000) - 1.
*
* This field is used to represent the micro-of-day handling any fraction of the second.
* Implementations of {@link TemporalAccessor} should provide a value for this field if they
* can return a value for `SECOND_OF_DAY` filling unknown precision with zero.
*
* When this field is used for setting a value, it should behave in the same way as
* setting `NANO_OF_DAY` with the value multiplied by 1,000.
*
* - `ChronoField.MICRO_OF_SECOND`: This counts the microsecond within the second, from 0
* to 999,999.
*
* This field is used to represent the micro-of-second handling any fraction of the second.
* Implementations of {@link TemporalAccessor} should provide a value for this field if they
* can return a value for `SECOND_OF_MINUTE`, `SECOND_OF_DAY` or `INSTANT_SECONDS` filling
* unknown precision with zero.
*
* - `ChronoField.MILLI_OF_DAY`: This counts the millisecond within the day, from 0 to
* (24 * 60 * 60 * 1,000) - 1.
*
* This field is used to represent the milli-of-day handling any fraction of the second.
* Implementations of {@link TemporalAccessor} should provide a value for this field if they
* can return a value for `SECOND_OF_DAY` filling unknown precision with zero.
*
* When this field is used for setting a value, it should behave in the same way as
* setting `NANO_OF_DAY` with the value multiplied by 1,000,000.
*
* - `ChronoField.MILLI_OF_SECOND`: This counts the millisecond within the second, from 0 to
* 999.
*
* This field is used to represent the milli-of-second handling any fraction of the second.
* Implementations of {@link TemporalAccessor} should provide a value for this field if they can
* return a value for `SECOND_OF_MINUTE`, `SECOND_OF_DAY` or `INSTANT_SECONDS` filling unknown
* precision with zero.
*
* When this field is used for setting a value, it should behave in the same way as
* setting `NANO_OF_SECOND` with the value multiplied by 1,000,000.
*
* - `ChronoField.MINUTE_OF_DAY`: This counts the minute within the day, from 0 to (24 * 60) - 1.
*
* - `ChronoField.MINUTE_OF_HOUR`: This counts the minute within the hour, from 0 to 59.
*
* - `ChronoField.MONTH_OF_YEAR`: The month-of-year, such as March. This represents the concept
* of the month within the year. In the default ISO calendar system, this has values from
* January (1) to December (12).
*
* - `ChronoField.NANO_OF_DAY`: This counts the nanosecond within the day, from 0 to
* (24 * 60 * 60 * 1,000,000,000) - 1.
*
* This field is used to represent the nano-of-day handling any fraction of the second.
* Implementations of {@link TemporalAccessor} should provide a value for this field if they
* can return a value for `SECOND_OF_DAY` filling unknown precision with zero.
*
* - `ChronoField.NANO_OF_SECOND`: This counts the nanosecond within the second, from 0
* to 999,999,999.
*
* This field is used to represent the nano-of-second handling any fraction of the second.
* Implementations of {@link TemporalAccessor} should provide a value for this field if they
* can return a value for `SECOND_OF_MINUTE`, `SECOND_OF_DAY` or `INSTANT_SECONDS` filling
* unknown precision with zero.
*
* When this field is used for setting a value, it should set as much precision as the
* object stores, using integer division to remove excess precision. For example, if the
* {@link TemporalAccessor} stores time to millisecond precision, then the nano-of-second must
* be divided by 1,000,000 before replacing the milli-of-second.
*
* - `ChronoField.OFFSET_SECONDS`: This represents the concept of the offset in seconds of
* local time from UTC/Greenwich.
*
* A {@link ZoneOffset} represents the period of time that local time differs from
* UTC/Greenwich. This is usually a fixed number of hours and minutes. It is equivalent to
* the total amount of the offset in seconds. For example, during the winter Paris has an
* offset of +01:00, which is 3600 seconds.
*
* - `ChronoField.PROLEPTIC_MONTH`: The proleptic-month, which counts months sequentially
* from year 0.
*
* The first month in year zero has the value zero. The value increase for later months
* and decrease for earlier ones. Note that this uses the local time-line, ignoring offset
* and time-zone.
*
* - `ChronoField.SECOND_OF_DAY`: This counts the second within the day, from 0 to
* (24 * 60 * 60) - 1.
*
* - `ChronoField.SECOND_OF_MINUTE`: This counts the second within the minute, from 0 to 59.
*
* - `ChronoField.YEAR`: The proleptic year, such as 2012. This represents the concept of
* the year, counting sequentially and using negative numbers. The proleptic year is not
* interpreted in terms of the era.
*
* The standard mental model for a date is based on three concepts - year, month and day.
* These map onto the `YEAR`, `MONTH_OF_YEAR` and `DAY_OF_MONTH` fields. Note that there is no
* reference to eras. The full model for a date requires four concepts - era, year, month and
* day. These map onto the `ERA`, `YEAR_OF_ERA`, `MONTH_OF_YEAR` and `DAY_OF_MONTH` fields.
* Whether this field or `YEAR_OF_ERA` is used depends on which mental model is being used.
*
* - `ChronoField.YEAR_OF_ERA`: This represents the concept of the year within the era. This
* field is typically used with `ERA`. The standard mental model for a date is based on three
* concepts - year, month and day. These map onto the `YEAR`, `MONTH_OF_YEAR` and
* `DAY_OF_MONTH` fields. Note that there is no reference to eras. The full model for a date
* requires four concepts - era, year, month and day. These map onto the `ERA`, `YEAR_OF_ERA`,
* `MONTH_OF_YEAR` and `DAY_OF_MONTH` fields. Whether this field or `YEAR` is used depends on
* which mental model is being used.
*
* In the default ISO calendar system, there are two eras defined, 'BCE' and 'CE'.
* The era 'CE' is the one currently in use and year-of-era runs from 1 to the maximum value.
* The era 'BCE' is the previous era, and the year-of-era runs backwards.
*
* For example, subtracting a year each time yield the following:
* - year-proleptic 2 = 'CE' year-of-era 2
* - year-proleptic 1 = 'CE' year-of-era 1
* - year-proleptic 0 = 'BCE' year-of-era 1
* - year-proleptic -1 = 'BCE' year-of-era 2
*
* Note that the ISO-8601 standard does not actually define eras. Note also that the
* ISO eras do not align with the well-known AD/BC eras due to the change between the Julian
* and Gregorian calendar systems.
*/
export class ChronoField extends TemporalField {
/**
* helper function to get one of the static ChronoField defines by name, needed to resolve ChronoField from EnumMap
*
* @param {String} fieldName
* @return {ChronoField | null}
* @private
*/
static byName(fieldName) {
for (const prop in ChronoField) {
if (ChronoField[prop]) {
if ((ChronoField[prop] instanceof ChronoField) && ChronoField[prop].name() === fieldName) {
return ChronoField[prop];
}
}
}
}
/**
*
* @param {!string} name
* @param {!TemporalUnit} baseUnit
* @param {!TemporalUnit} rangeUnit
* @param {!ValueRange} range
* @private
*/
constructor(name, baseUnit, rangeUnit, range) {
super();
this._name = name;
this._baseUnit = baseUnit;
this._rangeUnit = rangeUnit;
this._range = range;
}
/**
* @return {string}
*/
name(){
return this._name;
}
/**
* @return {TemporalUnit} the period unit defining the base unit of the field.
*/
baseUnit(){
return this._baseUnit;
}
/**
* @return {TemporalUnit} the period unit defining the range of the field.
*/
rangeUnit(){
return this._rangeUnit;
}
/**
* @return {ValueRange} the range of valid values for the field.
*/
range(){
return this._range;
}
/**
* @returns {string}
*/
displayName(){
return this.toString();
}
/**
* Checks that the specified value is valid for this field.
*
* This validates that the value is within the outer range of valid values
* returned by {@link range}.
*
* This method checks against the range of the field in the ISO-8601 calendar system.
*
* @param {!number} value the value to check.
* @returns {number} the value that was passed in.
*/
checkValidValue(value) {
return this.range().checkValidValue(value, this);
}
/**
* Checks that the specified value is valid and fits in an `int`.
*
* This validates that the value is within the outer range of valid values
* returned by {@link range}.
* It also checks that all valid values are within the bounds of an `int`.
*
* This method checks against the range of the field in the ISO-8601 calendar system.
*
* @param {number} value the value to check.
* @return {number} the value that was passed in.
*/
checkValidIntValue(value) {
return this.range().checkValidIntValue(value, this);
}
/**
* @return {boolean} `true` if it is a component of a date, `false` otherwise.
*/
isDateBased() {
const dateBased =
this === ChronoField.DAY_OF_WEEK ||
this === ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH ||
this === ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR ||
this === ChronoField.DAY_OF_MONTH ||
this === ChronoField.DAY_OF_YEAR ||
this === ChronoField.EPOCH_DAY ||
this === ChronoField.ALIGNED_WEEK_OF_MONTH ||
this === ChronoField.ALIGNED_WEEK_OF_YEAR ||
this === ChronoField.MONTH_OF_YEAR ||
this === ChronoField.PROLEPTIC_MONTH ||
this === ChronoField.YEAR_OF_ERA ||
this === ChronoField.YEAR ||
this === ChronoField.ERA;
return dateBased;
}
/**
* @return {boolean} `true` if it is a component of a time, `false` otherwise.
*/
isTimeBased() {
const timeBased =
this === ChronoField.NANO_OF_SECOND ||
this === ChronoField.NANO_OF_DAY ||
this === ChronoField.MICRO_OF_SECOND ||
this === ChronoField.MICRO_OF_DAY ||
this === ChronoField.MILLI_OF_SECOND ||
this === ChronoField.MILLI_OF_DAY ||
this === ChronoField.SECOND_OF_MINUTE ||
this === ChronoField.SECOND_OF_DAY ||
this === ChronoField.MINUTE_OF_HOUR ||
this === ChronoField.MINUTE_OF_DAY ||
this === ChronoField.HOUR_OF_AMPM ||
this === ChronoField.CLOCK_HOUR_OF_AMPM ||
this === ChronoField.HOUR_OF_DAY ||
this === ChronoField.CLOCK_HOUR_OF_DAY ||
this === ChronoField.AMPM_OF_DAY;
return timeBased;
}
/**
* @param {!TemporalAccessor} temporal the temporal object used to refine the result.
* @return {ValueRange} the range of valid values for this field.
* @throws {DateTimeException} if the range for the field cannot be obtained.
*/
rangeRefinedBy(temporal) {
return temporal.range(this);
}
/**
* @param {!TemporalAccesor} temporal the temporal object to query.
* @return {number} the value of this field.
* @throws {DateTimeException} if a value for the field cannot be obtained.
*/
getFrom(temporal) {
return temporal.getLong(this);
}
/**
* @returns {string}
*/
toString(){
return this.name();
}
/**
* @param {*} other
* @returns {boolean}
*/
equals(other){
return this === other;
}
/**
* @param {!Temporal} temporal the temporal object to adjust.
* @param {!number} newValue the new value of the field.
* @return {Temporal} the adjusted temporal object.
* @throws {DateTimeException} if the field cannot be set.
*/
adjustInto(temporal, newValue) {
return temporal.with(this, newValue);
}
/**
* @param {!TemporalAccesor} temporal the temporal object to query.
* @return {boolean} `true` if the date-time can be queried for this field, `false` if not.
*/
isSupportedBy(temporal) {
return temporal.isSupported(this);
}
}
export function _init() {
ChronoField.NANO_OF_SECOND = new ChronoField('NanoOfSecond', ChronoUnit.NANOS, ChronoUnit.SECONDS, ValueRange.of(0, 999999999));
ChronoField.NANO_OF_DAY = new ChronoField('NanoOfDay', ChronoUnit.NANOS, ChronoUnit.DAYS, ValueRange.of(0, 86400 * 1000000000 - 1));
ChronoField.MICRO_OF_SECOND = new ChronoField('MicroOfSecond', ChronoUnit.MICROS, ChronoUnit.SECONDS, ValueRange.of(0, 999999));
ChronoField.MICRO_OF_DAY = new ChronoField('MicroOfDay', ChronoUnit.MICROS, ChronoUnit.DAYS, ValueRange.of(0, 86400 * 1000000 - 1));
ChronoField.MILLI_OF_SECOND = new ChronoField('MilliOfSecond', ChronoUnit.MILLIS, ChronoUnit.SECONDS, ValueRange.of(0, 999));
ChronoField.MILLI_OF_DAY = new ChronoField('MilliOfDay', ChronoUnit.MILLIS, ChronoUnit.DAYS, ValueRange.of(0, 86400 * 1000 - 1));
ChronoField.SECOND_OF_MINUTE = new ChronoField('SecondOfMinute', ChronoUnit.SECONDS, ChronoUnit.MINUTES, ValueRange.of(0, 59));
ChronoField.SECOND_OF_DAY = new ChronoField('SecondOfDay', ChronoUnit.SECONDS, ChronoUnit.DAYS, ValueRange.of(0, 86400 - 1));
ChronoField.MINUTE_OF_HOUR = new ChronoField('MinuteOfHour', ChronoUnit.MINUTES, ChronoUnit.HOURS, ValueRange.of(0, 59));
ChronoField.MINUTE_OF_DAY = new ChronoField('MinuteOfDay', ChronoUnit.MINUTES, ChronoUnit.DAYS, ValueRange.of(0, (24 * 60) - 1));
ChronoField.HOUR_OF_AMPM = new ChronoField('HourOfAmPm', ChronoUnit.HOURS, ChronoUnit.HALF_DAYS, ValueRange.of(0, 11));
ChronoField.CLOCK_HOUR_OF_AMPM = new ChronoField('ClockHourOfAmPm', ChronoUnit.HOURS, ChronoUnit.HALF_DAYS, ValueRange.of(1, 12));
ChronoField.HOUR_OF_DAY = new ChronoField('HourOfDay', ChronoUnit.HOURS, ChronoUnit.DAYS, ValueRange.of(0, 23));
ChronoField.CLOCK_HOUR_OF_DAY = new ChronoField('ClockHourOfDay', ChronoUnit.HOURS, ChronoUnit.DAYS, ValueRange.of(1, 24));
ChronoField.AMPM_OF_DAY = new ChronoField('AmPmOfDay', ChronoUnit.HALF_DAYS, ChronoUnit.DAYS, ValueRange.of(0, 1));
ChronoField.DAY_OF_WEEK = new ChronoField('DayOfWeek', ChronoUnit.DAYS, ChronoUnit.WEEKS, ValueRange.of(1, 7));
ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH = new ChronoField('AlignedDayOfWeekInMonth', ChronoUnit.DAYS, ChronoUnit.WEEKS, ValueRange.of(1, 7));
ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR = new ChronoField('AlignedDayOfWeekInYear', ChronoUnit.DAYS, ChronoUnit.WEEKS, ValueRange.of(1, 7));
ChronoField.DAY_OF_MONTH = new ChronoField('DayOfMonth', ChronoUnit.DAYS, ChronoUnit.MONTHS, ValueRange.of(1, 28, 31), 'day');
ChronoField.DAY_OF_YEAR = new ChronoField('DayOfYear', ChronoUnit.DAYS, ChronoUnit.YEARS, ValueRange.of(1, 365, 366));
ChronoField.EPOCH_DAY = new ChronoField('EpochDay', ChronoUnit.DAYS, ChronoUnit.FOREVER, ValueRange.of(-365961662, 364522971)); // [LocalDate.MIN.toEpochDay() .. LocalDate.MAX.toEpochDay()]
ChronoField.ALIGNED_WEEK_OF_MONTH = new ChronoField('AlignedWeekOfMonth', ChronoUnit.WEEKS, ChronoUnit.MONTHS, ValueRange.of(1, 4, 5));
ChronoField.ALIGNED_WEEK_OF_YEAR = new ChronoField('AlignedWeekOfYear', ChronoUnit.WEEKS, ChronoUnit.YEARS, ValueRange.of(1, 53));
ChronoField.MONTH_OF_YEAR = new ChronoField('MonthOfYear', ChronoUnit.MONTHS, ChronoUnit.YEARS, ValueRange.of(1, 12), 'month');
ChronoField.PROLEPTIC_MONTH = new ChronoField('ProlepticMonth', ChronoUnit.MONTHS, ChronoUnit.FOREVER, ValueRange.of(YearConstants.MIN_VALUE * 12, YearConstants.MAX_VALUE * 12 + 11));
ChronoField.YEAR_OF_ERA = new ChronoField('YearOfEra', ChronoUnit.YEARS, ChronoUnit.FOREVER, ValueRange.of(1, YearConstants.MAX_VALUE, YearConstants.MAX_VALUE + 1));
ChronoField.YEAR = new ChronoField('Year', ChronoUnit.YEARS, ChronoUnit.FOREVER, ValueRange.of(YearConstants.MIN_VALUE, YearConstants.MAX_VALUE), 'year');
ChronoField.ERA = new ChronoField('Era', ChronoUnit.ERAS, ChronoUnit.FOREVER, ValueRange.of(0, 1));
ChronoField.INSTANT_SECONDS = new ChronoField('InstantSeconds', ChronoUnit.SECONDS, ChronoUnit.FOREVER, ValueRange.of(MIN_SAFE_INTEGER, MAX_SAFE_INTEGER));
ChronoField.OFFSET_SECONDS = new ChronoField('OffsetSeconds', ChronoUnit.SECONDS, ChronoUnit.FOREVER, ValueRange.of(-18 * 3600, 18 * 3600));
}

310
node_modules/@js-joda/core/src/temporal/ChronoUnit.js generated vendored Normal file
View File

@@ -0,0 +1,310 @@
/**
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
import { MathUtil } from '../MathUtil';
import { Duration } from '../Duration';
import { YearConstants } from '../YearConstants';
import { TemporalUnit } from './TemporalUnit';
/**
* A standard set of date periods units.
*
* This set of units provide unit-based access to manipulate a date, time or date-time.
* The standard set of units can be extended by implementing {@link TemporalUnit}.
*
* These units are intended to be applicable in multiple calendar systems.
* For example, most non-ISO calendar systems define units of years, months and days,
* just with slightly different rules.
* The documentation of each unit explains how it operates.
*
* ### Static properties:
*
* - `ChronoUnit.CENTURIES`: Unit that represents the concept of a century. For the ISO calendar
* system, it is equal to 100 years.
*
* - `ChronoUnit.DAYS`: Unit that represents the concept of a day. For the ISO calendar system, it
* is the standard day from midnight to midnight. The estimated duration of a day is 24 Hours.
*
* - `ChronoUnit.DECADES`: Unit that represents the concept of a decade. For the ISO calendar system,
* it is equal to 10 years.
*
* - `ChronoUnit.ERAS`: Unit that represents the concept of an era. The ISO calendar system doesn't
* have eras thus it is impossible to add an era to a date or date-time. The estimated duration of the
* era is artificially defined as 1,000,000,000 Years.
*
* - `ChronoUnit.FOREVER`: Artificial unit that represents the concept of forever. This is primarily
* used with {@link TemporalField} to represent unbounded fields such as the year or era. The
* estimated duration of the era is artificially defined as the largest duration supported by
* {@link Duration}.
*
* - `ChronoUnit.HALF_DAYS`: Unit that represents the concept of half a day, as used in AM/PM. For
* the ISO calendar system, it is equal to 12 hours.
*
* - `ChronoUnit.HOURS`: Unit that represents the concept of an hour. For the ISO calendar system,
* it is equal to 60 minutes.
*
* - `ChronoUnit.MICROS`: Unit that represents the concept of a microsecond. For the ISO calendar
* system, it is equal to the 1,000,000th part of the second unit.
*
* - `ChronoUnit.MILLENNIA`: Unit that represents the concept of a millennium. For the ISO calendar
* system, it is equal to 1,000 years.
*
* - `ChronoUnit.MILLIS`: Unit that represents the concept of a millisecond. For the ISO calendar
* system, it is equal to the 1000th part of the second unit.
*
* - `ChronoUnit.MINUTES`: Unit that represents the concept of a minute. For the ISO calendar system,
* it is equal to 60 seconds.
*
* - `ChronoUnit.MONTHS`: Unit that represents the concept of a month. For the ISO calendar system,
* the length of the month varies by month-of-year. The estimated duration of a month is one twelfth
* of 365.2425 Days.
*
* - `ChronoUnit.NANOS`: Unit that represents the concept of a nanosecond, the smallest supported unit
* of time. For the ISO calendar system, it is equal to the 1,000,000,000th part of the second unit.
*
* - `ChronoUnit.SECONDS`: Unit that represents the concept of a second. For the ISO calendar system,
* it is equal to the second in the SI system of units, except around a leap-second.
*
* - `ChronoUnit.WEEKS`: Unit that represents the concept of a week. For the ISO calendar system,
* it is equal to 7 Days.
*
* - `ChronoUnit.YEARS`: Unit that represents the concept of a year. For the ISO calendar system, it
* is equal to 12 months. The estimated duration of a year is 365.2425 Days.
*/
export class ChronoUnit extends TemporalUnit {
/**
*
* @param {String} name
* @param {Duration} estimatedDuration
* @private
*/
constructor (name, estimatedDuration) {
super();
this._name = name;
this._duration = estimatedDuration;
}
//-----------------------------------------------------------------------
/**
* @return {Duration} the duration of this unit, which may be an estimate.
*/
duration() {
return this._duration;
}
/**
* @return {boolean} `true` if the duration is estimated, `false` if accurate.
*/
isDurationEstimated() {
return this.isDateBased() || this === ChronoUnit.FOREVER;
}
//-----------------------------------------------------------------------
/**
* @return {boolean} `true` if date unit, `false` if a time unit.
*/
isDateBased() {
return this.compareTo(ChronoUnit.DAYS) >= 0 && this !== ChronoUnit.FOREVER;
}
/**
* Checks if this unit is a time unit.
*
* @return {boolean} `true` if time unit, `false` if a date unit.
*/
isTimeBased() {
return this.compareTo(ChronoUnit.DAYS) < 0;
}
//-----------------------------------------------------------------------
/**
* @param {!Temporal} temporal the temporal object to check.
* @return {boolean} `true` if the unit is supported.
*/
isSupportedBy(temporal) {
if (this === ChronoUnit.FOREVER) {
return false;
}
/* TODO: classes not implemented yet */
/*
if (temporal instanceof ChronoLocalDate) {
return isDateBased();
}
if (temporal instanceof ChronoLocalDateTime || temporal instanceof ChronoZonedDateTime) {
return true;
}
*/
try {
temporal.plus(1, this);
return true;
} catch (e) {
try {
temporal.plus(-1, this);
return true;
} catch (e2) {
return false;
}
}
}
/**
* @param {!Temporal} temporal the temporal object to adjust.
* @param {number} amount the period of this unit to add, positive or negative.
* @return {Temporal} the adjusted temporal object.
* @throws DateTimeException if the period cannot be added.
*/
addTo(temporal, amount) {
return temporal.plus(amount, this);
}
//-----------------------------------------------------------------------
/**
* @param {!Temporal} temporal1 the base temporal object.
* @param {!Temporal} temporal2 the other temporal object.
* @return {number} the period between temporal1 and temporal2 in terms of this unit;
* positive if temporal2 is later than temporal1, negative if earlier.
* @throws DateTimeException if the period cannot be calculated.
* @throws ArithmeticException if numeric overflow occurs.
*/
between(temporal1, temporal2) {
return temporal1.until(temporal2, this);
}
//-----------------------------------------------------------------------
toString() {
return this._name;
}
/**
* Compares this ChronoUnit to the specified {@link TemporalUnit}.
*
* The comparison is based on the total length of the durations.
*
* @param {!TemporalUnit} other the other unit to compare to.
* @return the comparator value, negative if less, positive if greater.
*/
compareTo(other) {
return this.duration().compareTo(other.duration());
}
}
export function _init() {
/**
* Unit that represents the concept of a nanosecond, the smallest supported unit of time.
* For the ISO calendar system, it is equal to the 1,000,000,000th part of the second unit.
*/
ChronoUnit.NANOS = new ChronoUnit('Nanos', Duration.ofNanos(1));
/**
* Unit that represents the concept of a microsecond.
* For the ISO calendar system, it is equal to the 1,000,000th part of the second unit.
*/
ChronoUnit.MICROS = new ChronoUnit('Micros', Duration.ofNanos(1000));
/**
* Unit that represents the concept of a millisecond.
* For the ISO calendar system, it is equal to the 1000th part of the second unit.
*/
ChronoUnit.MILLIS = new ChronoUnit('Millis', Duration.ofNanos(1000000));
/**
* Unit that represents the concept of a second.
* For the ISO calendar system, it is equal to the second in the SI system
* of units, except around a leap-second.
*/
ChronoUnit.SECONDS = new ChronoUnit('Seconds', Duration.ofSeconds(1));
/**
* Unit that represents the concept of a minute.
* For the ISO calendar system, it is equal to 60 seconds.
*/
ChronoUnit.MINUTES = new ChronoUnit('Minutes', Duration.ofSeconds(60));
/**
* Unit that represents the concept of an hour.
* For the ISO calendar system, it is equal to 60 minutes.
*/
ChronoUnit.HOURS = new ChronoUnit('Hours', Duration.ofSeconds(3600));
/**
* Unit that represents the concept of half a day, as used in AM/PM.
* For the ISO calendar system, it is equal to 12 hours.
*/
ChronoUnit.HALF_DAYS = new ChronoUnit('HalfDays', Duration.ofSeconds(43200));
/**
* Unit that represents the concept of a day.
* For the ISO calendar system, it is the standard day from midnight to midnight.
* The estimated duration of a day is 24 hours.
*
* When used with other calendar systems it must correspond to the day defined by
* the rising and setting of the Sun on Earth. It is not required that days begin
* at midnight - when converting between calendar systems, the date should be
* equivalent at midday.
*/
ChronoUnit.DAYS = new ChronoUnit('Days', Duration.ofSeconds(86400));
/**
* Unit that represents the concept of a week.
* For the ISO calendar system, it is equal to 7 days.
*
* When used with other calendar systems it must correspond to an integral number of days.
*/
ChronoUnit.WEEKS = new ChronoUnit('Weeks', Duration.ofSeconds(7 * 86400));
/**
* Unit that represents the concept of a month.
* For the ISO calendar system, the length of the month varies by month-of-year.
* The estimated duration of a month is one twelfth of 365.2425 days.
*
* When used with other calendar systems it must correspond to an integral number of days.
*/
ChronoUnit.MONTHS = new ChronoUnit('Months', Duration.ofSeconds(31556952 / 12));
/**
* Unit that represents the concept of a year.
* For the ISO calendar system, it is equal to 12 months.
* The estimated duration of a year is 365.2425 days.
*
* When used with other calendar systems it must correspond to an integral number of days
* or months roughly equal to a year defined by the passage of the Earth around the Sun.
*/
ChronoUnit.YEARS = new ChronoUnit('Years', Duration.ofSeconds(31556952));
/**
* Unit that represents the concept of a decade.
* For the ISO calendar system, it is equal to 10 years.
*
* When used with other calendar systems it must correspond to an integral number of days
* and is normally an integral number of years.
*/
ChronoUnit.DECADES = new ChronoUnit('Decades', Duration.ofSeconds(31556952 * 10));
/**
* Unit that represents the concept of a century.
* For the ISO calendar system, it is equal to 100 years.
*
* When used with other calendar systems it must correspond to an integral number of days
* and is normally an integral number of years.
*/
ChronoUnit.CENTURIES = new ChronoUnit('Centuries', Duration.ofSeconds(31556952 * 100));
/**
* Unit that represents the concept of a millennium.
* For the ISO calendar system, it is equal to 1000 years.
*
* When used with other calendar systems it must correspond to an integral number of days
* and is normally an integral number of years.
*/
ChronoUnit.MILLENNIA = new ChronoUnit('Millennia', Duration.ofSeconds(31556952 * 1000));
/**
* Unit that represents the concept of an era.
* The ISO calendar system doesn't have eras thus it is impossible to add
* an era to a date or date-time.
* The estimated duration of the era is artificially defined as {Year.MAX_VALUE} + 1.
*
* When used with other calendar systems there are no restrictions on the unit.
*/
ChronoUnit.ERAS = new ChronoUnit('Eras', Duration.ofSeconds(31556952 * (YearConstants.MAX_VALUE + 1)));
/**
* Artificial unit that represents the concept of forever.
* This is primarily used with {@link TemporalField} to represent unbounded fields
* such as the year or era.
* The estimated duration of the era is artificially defined as the largest duration
* supported by {@link Duration}.
*/
ChronoUnit.FOREVER = new ChronoUnit('Forever', Duration.ofSeconds(MathUtil.MAX_SAFE_INTEGER, 999999999));
}

859
node_modules/@js-joda/core/src/temporal/IsoFields.js generated vendored Normal file
View File

@@ -0,0 +1,859 @@
/*
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
import { UnsupportedTemporalTypeException, IllegalStateException } from '../errors';
import { DayOfWeek } from '../DayOfWeek';
import { Duration } from '../Duration';
import { MathUtil } from '../MathUtil';
import { LocalDate } from '../LocalDate';
import { ChronoField } from './ChronoField';
import { ChronoUnit } from './ChronoUnit';
import { TemporalField } from './TemporalField';
import { TemporalUnit } from './TemporalUnit';
import { ValueRange } from './ValueRange';
import { IsoChronology } from '../chrono/IsoChronology';
import { ResolverStyle } from '../format/ResolverStyle';
/**
* Fields and units specific to the ISO-8601 calendar system,
* including quarter-of-year and week-based-year.
*
* This class defines fields and units that are specific to the ISO calendar system.
*
* ### Quarter of year
*
* The ISO-8601 standard is based on the standard civic 12 month year.
* This is commonly divided into four quarters, often abbreviated as Q1, Q2, Q3 and Q4.
*
* January, February and March are in Q1.
* April, May and June are in Q2.
* July, August and September are in Q3.
* October, November and December are in Q4.
*
* The complete date is expressed using three fields:
*
* * `IsoFields.DAY_OF_QUARTER` - the day within the quarter, from 1 to 90, 91 or 92
* * `QUARTER_OF_YEAR` - the week within the week-based-year
* * `ChronoField.YEAR` - the standard ISO year (see {@link ChronoField})
*
* ### Week based years
*
* The ISO-8601 standard was originally intended as a data interchange format,
* defining a string format for dates and times. However, it also defines an
* alternate way of expressing the date, based on the concept of week-based-year.
*
* The date is expressed using three fields:
*
* * `ChronoField.DAY_OF_WEEK` - the standard field defining the
* day-of-week from Monday (1) to Sunday (7) (see {@link ChronoField})
* * `WEEK_OF_WEEK_BASED_YEAR` - the week within the week-based-year
* * `WEEK_BASED_YEAR` - the week-based-year
*
* The week-based-year itself is defined relative to the standard ISO proleptic year.
* It differs from the standard year in that it always starts on a Monday.
*
* The first week of a week-based-year is the first Monday-based week of the standard
* ISO year that has at least 4 days in the new year.
*
* * If January 1st is Monday then week 1 starts on January 1st
* * If January 1st is Tuesday then week 1 starts on December 31st of the previous standard year
* * If January 1st is Wednesday then week 1 starts on December 30th of the previous standard year
* * If January 1st is Thursday then week 1 starts on December 29th of the previous standard year
* * If January 1st is Friday then week 1 starts on January 4th
* * If January 1st is Saturday then week 1 starts on January 3rd
* * If January 1st is Sunday then week 1 starts on January 2nd
*
* There are 52 weeks in most week-based years, however on occasion there are 53 weeks.
*
* For example:
*
* * Sunday, 2008-12-28: Week 52 of week-based-year 2008
* * Monday, 2008-12-29: Week 1 of week-based-year 2009
* * Wednesday, 2008-12-31: Week 1 of week-based-year 2009
* * Thursday, 2009-01-01: Week 1 of week-based-year 2009
* * Sunday, 2009-01-04: Week 1 of week-based-year 2009
* * Monday, 2009-01-05: Week 2 of week-based-year 2009
*
* @property {TemporalField} DAY_OF_QUARTER The field that represents the day-of-quarter.
*
* This field allows the day-of-quarter value to be queried and set.
* The day-of-quarter has values from 1 to 90 in Q1 of a standard year, from 1 to 91
* in Q1 of a leap year, from 1 to 91 in Q2 and from 1 to 92 in Q3 and Q4.
*
* The day-of-quarter can only be calculated if the day-of-year, month-of-year and year
* are available.
*
* When setting this field, the value is allowed to be partially lenient, taking any
* value from 1 to 92. If the quarter has less than 92 days, then day 92, and
* potentially day 91, is in the following quarter.
*
* @property {TemporalField} QUARTER_OF_YEAR The field that represents the quarter-of-year.
*
* This field allows the quarter-of-year value to be queried and set.
* The quarter-of-year has values from 1 to 4.
*
* The day-of-quarter can only be calculated if the month-of-year is available.
*
* @property {TemporalField} WEEK_OF_WEEK_BASED_YEAR The field that represents the
* week-of-week-based-year.
*
* This field allows the week of the week-based-year value to be queried and set.
*
* @property {TemporalField} WEEK_BASED_YEAR The field that represents the week-based-year.
*
* This field allows the week-based-year value to be queried and set.
*
* @property {TemporalField} WEEK_BASED_YEARS The unit that represents week-based-years for
* the purpose of addition and subtraction.
*
* This allows a number of week-based-years to be added to, or subtracted from, a date.
* The unit is equal to either 52 or 53 weeks.
* The estimated duration of a week-based-year is the same as that of a standard ISO
* year at 365.2425 days.
*
* The rules for addition add the number of week-based-years to the existing value
* for the week-based-year field. If the resulting week-based-year only has 52 weeks,
* then the date will be in week 1 of the following week-based-year.
*
* @property {TemporalField} QUARTER_YEARS Unit that represents the concept of a quarter-year.
* For the ISO calendar system, it is equal to 3 months.
* The estimated duration of a quarter-year is one quarter of 365.2425 days.
*
* @typedef {Object} IsoFields
* @type {Object}
*/
export const IsoFields = {};
//-----------------------------------------------------------------------
const QUARTER_DAYS = [0, 90, 181, 273, 0, 91, 182, 274];
/**
* Implementation of the field.
* @private
*/
class Field extends TemporalField{
/**
*
* @returns {boolean}
*/
isDateBased() {
return true;
}
/**
*
* @returns {boolean}
*/
isTimeBased() {
return false;
}
/**
*
* @returns {boolean}
*/
_isIso() {
return true;
}
/**
*
* @param {LocalDate} date
* @returns {ValueRange}
*/
static _getWeekRangeByLocalDate(date) {
const wby = Field._getWeekBasedYear(date);
return ValueRange.of(1, Field._getWeekRangeByYear(wby));
}
/**
*
* @param {number} wby
* @returns {number}
*/
static _getWeekRangeByYear(wby) {
const date = LocalDate.of(wby, 1, 1);
// 53 weeks if standard year starts on Thursday, or Wed in a leap year
if (date.dayOfWeek() === DayOfWeek.THURSDAY || (date.dayOfWeek() === DayOfWeek.WEDNESDAY && date.isLeapYear())) {
return 53;
}
return 52;
}
/**
*
* @param {LocalDate} date
* @returns {number}
*/
static _getWeek(date) {
const dow0 = date.dayOfWeek().ordinal();
const doy0 = date.dayOfYear() - 1;
const doyThu0 = doy0 + (3 - dow0); // adjust to mid-week Thursday (which is 3 indexed from zero)
const alignedWeek = MathUtil.intDiv(doyThu0, 7);
const firstThuDoy0 = doyThu0 - (alignedWeek * 7);
let firstMonDoy0 = firstThuDoy0 - 3;
if (firstMonDoy0 < -3) {
firstMonDoy0 += 7;
}
if (doy0 < firstMonDoy0) {
return Field._getWeekRangeByLocalDate(date.withDayOfYear(180).minusYears(1)).maximum();
}
let week = MathUtil.intDiv((doy0 - firstMonDoy0), 7) + 1;
if (week === 53) {
if ((firstMonDoy0 === -3 || (firstMonDoy0 === -2 && date.isLeapYear())) === false) {
week = 1;
}
}
return week;
}
/**
*
* @param {LocalDate} date
* @returns {number}
*/
static _getWeekBasedYear(date) {
let year = date.year();
let doy = date.dayOfYear();
if (doy <= 3) {
const dow = date.dayOfWeek().ordinal();
if (doy - dow < -2) {
year--;
}
} else if (doy >= 363) {
const dow = date.dayOfWeek().ordinal();
doy = doy - 363 - (date.isLeapYear() ? 1 : 0);
if (doy - dow >= 0) {
year++;
}
}
return year;
}
/**
*
* @returns {string}
*/
displayName(/*locale*/) {
return this.toString();
}
/**
*
* @returns {null}
*/
resolve() {
return null;
}
name(){
return this.toString();
}
}
/**
* @private
*/
class DAY_OF_QUARTER_FIELD extends Field {
/**
*
* @returns {string}
*/
toString() {
return 'DayOfQuarter';
}
/**
*
* @returns {TemporalUnit}
*/
baseUnit() {
return ChronoUnit.DAYS;
}
/**
*
* @returns {TemporalUnit}
*/
rangeUnit() {
return QUARTER_YEARS;
}
/**
*
* @returns {ValueRange}
*/
range() {
return ValueRange.of(1, 90, 92);
}
/**
*
* @param {TemporalAccessor} temporal
* @returns {boolean}
*/
isSupportedBy(temporal) {
return temporal.isSupported(ChronoField.DAY_OF_YEAR) && temporal.isSupported(ChronoField.MONTH_OF_YEAR) &&
temporal.isSupported(ChronoField.YEAR) && this._isIso(temporal);
}
/**
*
* @param {TemporalAccessor} temporal
* @returns {ValueRange}
*/
rangeRefinedBy(temporal) {
if (temporal.isSupported(this) === false) {
throw new UnsupportedTemporalTypeException('Unsupported field: DayOfQuarter');
}
const qoy = temporal.getLong(QUARTER_OF_YEAR);
if (qoy === 1) {
const year = temporal.getLong(ChronoField.YEAR);
return (IsoChronology.isLeapYear(year) ? ValueRange.of(1, 91) : ValueRange.of(1, 90));
} else if (qoy === 2) {
return ValueRange.of(1, 91);
} else if (qoy === 3 || qoy === 4) {
return ValueRange.of(1, 92);
} // else value not from 1 to 4, so drop through
return this.range();
}
/**
*
* @param {TemporalAccessor} temporal
* @returns {number}
*/
getFrom(temporal) {
if (temporal.isSupported(this) === false) {
throw new UnsupportedTemporalTypeException('Unsupported field: DayOfQuarter');
}
const doy = temporal.get(ChronoField.DAY_OF_YEAR);
const moy = temporal.get(ChronoField.MONTH_OF_YEAR);
const year = temporal.getLong(ChronoField.YEAR);
return doy - QUARTER_DAYS[MathUtil.intDiv((moy - 1), 3) + (IsoChronology.isLeapYear(year) ? 4 : 0)];
}
/**
*
* @param {Temporal} temporal
* @param {number} newValue
* @returns {temporal}
*/
adjustInto(temporal, newValue) {
const curValue = this.getFrom(temporal);
this.range().checkValidValue(newValue, this);
return temporal.with(ChronoField.DAY_OF_YEAR, temporal.getLong(ChronoField.DAY_OF_YEAR) + (newValue - curValue));
}
/**
*
* @param {Map<TemporalField, number>} fieldValues
* @param {TemporalAccessor} partialTemporal
* @param {ResolverStyle} resolverStyle
* @returns {ValueRange}
*/
resolve(fieldValues, partialTemporal, resolverStyle) {
const yearLong = fieldValues.get(ChronoField.YEAR);
const qoyLong = fieldValues.get(QUARTER_OF_YEAR);
if (yearLong == null || qoyLong == null) {
return null;
}
const y = ChronoField.YEAR.checkValidIntValue(yearLong);
const doq = fieldValues.get(DAY_OF_QUARTER);
let date;
if (resolverStyle === ResolverStyle.LENIENT) {
const qoy = qoyLong;
date = LocalDate.of(y, 1, 1);
date = date.plusMonths(MathUtil.safeMultiply(MathUtil.safeSubtract(qoy, 1), 3));
date = date.plusDays(MathUtil.safeSubtract(doq, 1));
} else {
const qoy = QUARTER_OF_YEAR.range().checkValidIntValue(qoyLong, QUARTER_OF_YEAR);
if (resolverStyle === ResolverStyle.STRICT) {
let max = 92;
if (qoy === 1) {
max = (IsoChronology.isLeapYear(y) ? 91 : 90);
} else if (qoy === 2) {
max = 91;
}
ValueRange.of(1, max).checkValidValue(doq, this);
} else {
this.range().checkValidValue(doq, this); // leniently check from 1 to 92
}
date = LocalDate.of(y, ((qoy - 1) * 3) + 1, 1).plusDays(doq - 1);
}
fieldValues.remove(this);
fieldValues.remove(ChronoField.YEAR);
fieldValues.remove(QUARTER_OF_YEAR);
return date;
}
}
/**
* @private
*/
class QUARTER_OF_YEAR_FIELD extends Field {
/**
*
* @returns {string}
*/
toString() {
return 'QuarterOfYear';
}
/**
*
* @returns {TemporalUnit}
*/
baseUnit() {
return QUARTER_YEARS;
}
/**
*
* @returns {TemporalUnit}
*/
rangeUnit() {
return ChronoUnit.YEARS;
}
/**
*
* @returns {ValueRange}
*/
range() {
return ValueRange.of(1, 4);
}
/**
*
* @param {TemporalAccessor} temporal
* @returns {boolean}
*/
isSupportedBy(temporal) {
return temporal.isSupported(ChronoField.MONTH_OF_YEAR) && this._isIso(temporal);
}
/**
*
* @param {TemporalAccessor} temporal
* @returns {ValueRange}
*/
//eslint-disable-next-line no-unused-vars
rangeRefinedBy(temporal) {
return this.range();
}
/**
*
* @param {TemporalAccessor} temporal
* @returns {number}
*/
getFrom(temporal) {
if (temporal.isSupported(this) === false) {
throw new UnsupportedTemporalTypeException('Unsupported field: QuarterOfYear');
}
const moy = temporal.getLong(ChronoField.MONTH_OF_YEAR);
return MathUtil.intDiv((moy + 2), 3);
}
/**
*
* @param {Temporal} temporal
* @param {number} newValue
* @returns {temporal}
*/
adjustInto(temporal, newValue) {
const curValue = this.getFrom(temporal);
this.range().checkValidValue(newValue, this);
return temporal.with(ChronoField.MONTH_OF_YEAR, temporal.getLong(ChronoField.MONTH_OF_YEAR) + (newValue - curValue) * 3);
}
}
/**
* @private
*/
class WEEK_OF_WEEK_BASED_YEAR_FIELD extends Field {
/**
*
* @returns {string}
*/
toString() {
return 'WeekOfWeekBasedYear';
}
/**
*
* @returns {TemporalUnit}
*/
baseUnit() {
return ChronoUnit.WEEKS;
}
/**
*
* @returns {TemporalUnit}
*/
rangeUnit() {
return WEEK_BASED_YEARS;
}
/**
*
* @returns {ValueRange}
*/
range() {
return ValueRange.of(1, 52, 53);
}
/**
*
* @param {TemporalAccessor} temporal
* @returns {boolean}
*/
isSupportedBy(temporal) {
return temporal.isSupported(ChronoField.EPOCH_DAY) && this._isIso(temporal);
}
/**
*
* @param {TemporalAccessor} temporal
* @returns {ValueRange}
*/
rangeRefinedBy(temporal) {
if (temporal.isSupported(this) === false) {
throw new UnsupportedTemporalTypeException('Unsupported field: WeekOfWeekBasedYear');
}
return Field._getWeekRangeByLocalDate(LocalDate.from(temporal));
}
/**
*
* @param {TemporalAccessor} temporal
* @returns {number}
*/
getFrom(temporal) {
if (temporal.isSupported(this) === false) {
throw new UnsupportedTemporalTypeException('Unsupported field: WeekOfWeekBasedYear');
}
return Field._getWeek(LocalDate.from(temporal));
}
/**
*
* @param {Temporal} temporal
* @param {number} newValue
* @returns {temporal}
*/
adjustInto(temporal, newValue) {
this.range().checkValidValue(newValue, this);
return temporal.plus(MathUtil.safeSubtract(newValue, this.getFrom(temporal)), ChronoUnit.WEEKS);
}
/**
*
* @param {Map<TemporalField, number>} fieldValues
* @param {TemporalAccessor} partialTemporal
* @param {ResolverStyle} resolverStyle
* @returns {ValueRange}
*/
resolve(fieldValues, partialTemporal, resolverStyle) {
const wbyLong = fieldValues.get(WEEK_BASED_YEAR);
const dowLong = fieldValues.get(ChronoField.DAY_OF_WEEK);
if (wbyLong == null || dowLong == null) {
return null;
}
const wby = WEEK_BASED_YEAR.range().checkValidIntValue(wbyLong, WEEK_BASED_YEAR);
const wowby = fieldValues.get(WEEK_OF_WEEK_BASED_YEAR);
let date;
if (resolverStyle === ResolverStyle.LENIENT) {
let dow = dowLong;
let weeks = 0;
if (dow > 7) {
weeks = MathUtil.intDiv((dow - 1), 7);
dow = (MathUtil.intMod((dow - 1), 7) + 1);
} else if (dow < 1) {
weeks = MathUtil.intDiv(dow, 7) - 1;
dow = MathUtil.intMod(dow, 7) + 7;
}
date = LocalDate.of(wby, 1, 4).plusWeeks(wowby - 1).plusWeeks(weeks).with(ChronoField.DAY_OF_WEEK, dow);
} else {
const dow = ChronoField.DAY_OF_WEEK.checkValidIntValue(dowLong);
if (resolverStyle === ResolverStyle.STRICT) {
const temp = LocalDate.of(wby, 1, 4);
const range = Field._getWeekRangeByLocalDate(temp);
range.checkValidValue(wowby, this);
} else {
this.range().checkValidValue(wowby, this); // leniently check from 1 to 53
}
date = LocalDate.of(wby, 1, 4).plusWeeks(wowby - 1).with(ChronoField.DAY_OF_WEEK, dow);
}
fieldValues.remove(this);
fieldValues.remove(WEEK_BASED_YEAR);
fieldValues.remove(ChronoField.DAY_OF_WEEK);
return date;
}
/**
*
* @returns {string}
*/
displayName() {
return 'Week';
}
}
/**
* @private
*/
class WEEK_BASED_YEAR_FIELD extends Field {
/**
*
* @returns {string}
*/
toString() {
return 'WeekBasedYear';
}
/**
*
* @returns {TemporalUnit}
*/
baseUnit() {
return WEEK_BASED_YEARS;
}
/**
*
* @returns {TemporalUnit}
*/
rangeUnit() {
return ChronoUnit.FOREVER;
}
/**
*
* @returns {ValueRange}
*/
range() {
return ChronoField.YEAR.range();
}
/**
*
* @param {TemporalAccessor} temporal
* @returns {boolean}
*/
isSupportedBy(temporal) {
return temporal.isSupported(ChronoField.EPOCH_DAY) && this._isIso(temporal);
}
/**
*
* @param {TemporalAccessor} temporal
* @returns {ValueRange}
*/
//eslint-disable-next-line no-unused-vars
rangeRefinedBy(temporal) {
return ChronoField.YEAR.range();
}
/**
*
* @param {TemporalAccessor} temporal
* @returns {number}
*/
getFrom(temporal) {
if (temporal.isSupported(this) === false) {
throw new UnsupportedTemporalTypeException('Unsupported field: WeekBasedYear');
}
return Field._getWeekBasedYear(LocalDate.from(temporal));
}
/**
*
* @param {Temporal} temporal
* @param {number} newValue
* @returns {temporal}
*/
adjustInto(temporal, newValue) {
if (this.isSupportedBy(temporal) === false) {
throw new UnsupportedTemporalTypeException('Unsupported field: WeekBasedYear');
}
const newWby = this.range().checkValidIntValue(newValue, WEEK_BASED_YEAR); // strict check
const date = LocalDate.from(temporal);
const dow = date.get(ChronoField.DAY_OF_WEEK);
let week = Field._getWeek(date);
if (week === 53 && Field._getWeekRangeByYear(newWby) === 52) {
week = 52;
}
let resolved = LocalDate.of(newWby, 1, 4); // 4th is guaranteed to be in week one
const days = (dow - resolved.get(ChronoField.DAY_OF_WEEK)) + ((week - 1) * 7);
resolved = resolved.plusDays(days);
return temporal.with(resolved);
}
}
//-----------------------------------------------------------------------
/**
* Implementation of the period unit.
* @private
*/
class Unit extends TemporalUnit {
/**
*
* @param {string} name
* @param {Duration} estimatedDuration
* @private
*/
constructor(name, estimatedDuration) {
super();
this._name = name;
this._duration = estimatedDuration;
}
/**
*
* @returns {Duration}
*/
duration() {
return this._duration;
}
/**
*
* @returns {boolean}
*/
isDurationEstimated() {
return true;
}
/**
*
* @returns {boolean}
*/
isDateBased() {
return true;
}
/**
*
* @returns {boolean}
*/
isTimeBased() {
return false;
}
/**
*
* @param {Temporal} temporal
* @returns {boolean}
*/
isSupportedBy(temporal) {
return temporal.isSupported(ChronoField.EPOCH_DAY);
}
/**
*
* @param {Temporal} temporal
* @param {number} periodToAdd
* @returns {number}
*/
addTo(temporal, periodToAdd) {
switch(this) {
case WEEK_BASED_YEARS: {
const added = MathUtil.safeAdd(temporal.get(WEEK_BASED_YEAR), periodToAdd);
return temporal.with(WEEK_BASED_YEAR, added);
}
case QUARTER_YEARS:
// no overflow (256 is multiple of 4)
return temporal.plus(MathUtil.intDiv(periodToAdd, 256), ChronoUnit.YEARS).plus(MathUtil.intMod(periodToAdd, 256) * 3, ChronoUnit.MONTHS);
default:
throw new IllegalStateException('Unreachable');
}
}
/**
*
* @param {Temporal} temporal1
* @param {Temporal} temporal2
* @returns {number}
*/
between(temporal1, temporal2) {
switch(this) {
case WEEK_BASED_YEARS:
return MathUtil.safeSubtract(temporal2.getLong(WEEK_BASED_YEAR), temporal1.getLong(WEEK_BASED_YEAR));
case QUARTER_YEARS:
return MathUtil.intDiv(temporal1.until(temporal2, ChronoUnit.MONTHS), 3);
default:
throw new IllegalStateException('Unreachable');
}
}
toString() {
return this._name;
}
}
let DAY_OF_QUARTER = null;
let QUARTER_OF_YEAR = null;
let WEEK_OF_WEEK_BASED_YEAR = null;
let WEEK_BASED_YEAR = null;
let WEEK_BASED_YEARS = null;
let QUARTER_YEARS = null;
export function _init() {
DAY_OF_QUARTER = new DAY_OF_QUARTER_FIELD();
QUARTER_OF_YEAR = new QUARTER_OF_YEAR_FIELD();
WEEK_OF_WEEK_BASED_YEAR = new WEEK_OF_WEEK_BASED_YEAR_FIELD();
WEEK_BASED_YEAR = new WEEK_BASED_YEAR_FIELD();
WEEK_BASED_YEARS = new Unit('WeekBasedYears', Duration.ofSeconds(31556952));
QUARTER_YEARS = new Unit('QuarterYears', Duration.ofSeconds(31556952 / 4));
IsoFields.DAY_OF_QUARTER = DAY_OF_QUARTER;
IsoFields.QUARTER_OF_YEAR = QUARTER_OF_YEAR;
IsoFields.WEEK_OF_WEEK_BASED_YEAR = WEEK_OF_WEEK_BASED_YEAR;
IsoFields.WEEK_BASED_YEAR = WEEK_BASED_YEAR;
IsoFields.WEEK_BASED_YEARS = WEEK_BASED_YEARS;
IsoFields.QUARTER_YEARS = QUARTER_YEARS;
// this differs from threeten, but for ease of use we bring back good old joda time functionality
/**
* the week of the week based year as defined by the ISO8601 Standard with a Monday-based week
*
* @returns {number} the week a the week based year
*/
LocalDate.prototype.isoWeekOfWeekyear = function () {
return this.get(IsoFields.WEEK_OF_WEEK_BASED_YEAR);
};
/**
* the year of the week based year as defined by the ISO8601 Standard with a Monday-based week
*
* @returns {number} the year a the week based year
*/
LocalDate.prototype.isoWeekyear = function () {
return this.get(IsoFields.WEEK_BASED_YEAR);
};
}

369
node_modules/@js-joda/core/src/temporal/Temporal.js generated vendored Normal file
View File

@@ -0,0 +1,369 @@
/*
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
import { assert, abstractMethodFail, requireInstance, requireNonNull } from '../assert';
import { IllegalArgumentException } from '../errors';
import { TemporalAccessor } from './TemporalAccessor';
import { TemporalAmount } from './TemporalAmount';
import { TemporalUnit } from './TemporalUnit';
/**
* Framework-level interface defining read-write access to a temporal object,
* such as a date, time, offset or some combination of these.
*
* This is the base interface type for date, time and offset objects that
* are complete enough to be manipulated using plus and minus.
* It is implemented by those classes that can provide and manipulate information
* as fields (see {@link TemporalField}) or queries (see {@link TemporalQuery}).
* See {@link TemporalAccessor} for the read-only version of this interface.
*
* Most date and time information can be represented as a number.
* These are modeled using {@link TemporalField} with the number held using
* a `long` to handle large values. Year, month and day-of-month are
* simple examples of fields, but they also include instant and offsets.
* See {@link ChronoField} for the standard set of fields.
*
* Two pieces of date/time information cannot be represented by numbers,
* the {@link Chronology} and the {@link ZoneId}.
* These can be accessed using the static methods defined on {@link TemporalQueries}.
*
* This interface is a framework-level interface that should not be widely
* used in application code. Instead, applications should create and pass
* around instances of concrete types, such as {@link LocalDate}.
* There are many reasons for this, part of which is that implementations
* of this interface may be in calendar systems other than ISO.
* See {@link ChronoLocalDate} for a fuller discussion of the issues.
*
* ### When to implement
*
* A class should implement this interface if it meets three criteria:
*
* * it provides access to date/time/offset information, as per {@link TemporalAccessor}
* * the set of fields are contiguous from the largest to the smallest
* * the set of fields are complete, such that no other field is needed to define the
* valid range of values for the fields that are represented
*
* Four examples make this clear:
*
* * {@link LocalDate} implements this interface as it represents a set of fields
* that are contiguous from days to forever and require no external information to determine
* the validity of each date. It is therefore able to implement plus/minus correctly.
* * {@link LocalTime} implements this interface as it represents a set of fields
* that are contiguous from nanos to within days and require no external information to determine
* validity. It is able to implement plus/minus correctly, by wrapping around the day.
* * {@link MonthDay}, the combination of month-of-year and day-of-month, does not implement
* this interface. While the combination is contiguous, from days to months within years,
* the combination does not have sufficient information to define the valid range of values
* for day-of-month. As such, it is unable to implement plus/minus correctly.
* * The combination day-of-week and day-of-month ("Friday the 13th") should not implement
* this interface. It does not represent a contiguous set of fields, as days to weeks overlaps
* days to months.
*
* @interface
*/
export class Temporal extends TemporalAccessor {
/**
* Checks if the specified unit is supported.
* This checks if the date-time can be queried for the specified unit. If false, then calling the plus and minus methods will throw an exception.
* ### Specification for implementors
* Implementations must check and handle all fields defined in {@link ChronoUnit}. If the field is supported, then true is returned, otherwise false
* If the field is not a {@link ChronoUnit}, then the result of this method is obtained by invoking `TemporalUnit.isSupportedBy(Temporal)` passing this as the argument.
* Implementations must not alter this object.
* @param {TemporalUnit} fieldOrUnit - the unit to check, null returns false
* @return {boolean} true if this date-time can be queried for the unit, false if not
*/
// eslint-disable-next-line no-unused-vars
isSupported(fieldOrUnit) {
abstractMethodFail('isSupported');
}
/**
* function overloading for {@link Temporal.plus}
*
* Called with 1 (or less) arguments, p1 is expected to be a {@link TemporalAmount} and {@link Temporal.minusAmount} is called.
*
* Otherwise {@link Temporal.minusAmountUnit} is called.
*
* @param {!(TemporalAmount|number)} amount
* @param {TemporalUnit} unit
* @return {Temporal}
*/
minus(amount, unit) {
if (arguments.length < 2) {
return this._minusAmount(amount);
} else {
return this._minusUnit(amount, unit);
}
}
/**
* Returns an object of the same type as this object with an amount subtracted.
* This adjusts this temporal, subtracting according to the rules of the specified amount. The
* amount is typically a {@link Period} but may be any other type implementing the {@link TemporalAmount} interface, such as Duration.
*
* Some example code indicating how and why this method is used:
*
* <pre>
* date = date.minus(period); // subtract a Period instance
* date = date.minus(duration); // subtract a Duration instance
* date = date.minus(workingDays(6)); // example user-written workingDays method
* </pre>
*
* Note that calling plus followed by minus is not guaranteed to return the same date-time.
*
* ### Specification for implementors
* Implementations must not alter either this object. Instead, an adjusted copy of the original
* must be returned. This provides equivalent, safe behavior for immutable and mutable
* implementations.
*
* @param {TemporalAmount} amount - the amount to subtract, not null
* @return {Temporal} an object of the same type with the specified adjustment made, not null
* @throws DateTimeException - if the subtraction cannot be made
* @throws ArithmeticException - if numeric overflow occurs
*/
_minusAmount(amount) {
requireNonNull(amount, 'amount');
requireInstance(amount, TemporalAmount, 'amount');
return amount.subtractFrom(this);
}
/**
* Returns an object of the same type as this object with the specified period subtracted.
* This method returns a new object based on this one with the specified period subtracted. For example, on a {@link LocalDate}, this could be used to subtract a number of years, months or days. The returned object will have the same observable type as this object.
*
* In some cases, changing a field is not fully defined. For example, if the target object is a date representing the 31st March, then subtracting one month would be unclear. In cases like this, the field is responsible for resolving the result. Typically it will choose the previous valid date, which would be the last valid day of February in this example.
*
* If the implementation represents a date-time that has boundaries, such {@link as} LocalTime, then the permitted units must include the boundary unit, but no multiples of the boundary unit. For example, {@link LocalTime} must accept `DAYS` but not `WEEKS` or `MONTHS`.
*
* ### Specification for implementors
* Implementations must behave in a manor equivalent to the default method behavior.
* Implementations must not alter either this object or the specified temporal object. Instead, an adjusted copy of the original must be returned. This provides equivalent, safe behavior for immutable and mutable implementations.
*
* @param {number} amountToSubtract - the amount of the specified unit to subtract, may be negative
* @param {TemporalUnit} unit - the unit of the period to subtract, not null
* @return {Temporal} an object of the same type with the specified period subtracted, not null
* @throws DateTimeException - if the unit cannot be subtracted
* @throws ArithmeticException - if numeric overflow occurs
*/
_minusUnit(amountToSubtract, unit) {
requireNonNull(amountToSubtract, 'amountToSubtract');
requireNonNull(unit, 'unit');
requireInstance(unit, TemporalUnit, 'unit');
return this._plusUnit(-amountToSubtract, unit);
}
/**
* function overloading for {@link Temporal.plus}
*
* Called with 1 (or less) arguments, p1 is expected to be a {@link TemporalAmount} and {@link Temporal.plusAmount} is called.
*
* Otherwise {@link Temporal.plusAmountUnit} is called.
*
* @param {!(TemporalAmount|number)} amount
* @param {TemporalUnit} unit
* @return {Temporal}
*/
plus(amount, unit) {
if (arguments.length < 2) {
return this._plusAmount(amount);
} else {
return this._plusUnit(amount, unit);
}
}
/**
* Returns an object of the same type as this object with an amount added.
* This adjusts this temporal, adding according to the rules of the specified amount. The amount is typically a {@link Period} but may be any other type implementing the {@link TemporalAmount} interface, such as {@link Duration}.
*
* Some example code indicating how and why this method is used:
*
* <pre>
* date = date.plus(period); // add a Period instance
* date = date.plus(duration); // add a Duration instance
* date = date.plus(workingDays(6)); // example user-written workingDays method
* </pre>
*
* Note that calling plus followed by minus is not guaranteed to return the same date-time.
*
* ### Specification for implementors
* Implementations must not alter either this object. Instead, an adjusted copy of the original must be returned. This provides equivalent, safe behavior for immutable and mutable implementations.
*
* @param {TemporalAmount} amount - the amount to add, not null
* @return {Temporal} an object of the same type with the specified adjustment made, not null
* @throws DateTimeException - if the addition cannot be made
* @throws ArithmeticException - if numeric overflow occurs
*/
_plusAmount(amount) {
requireNonNull(amount, 'amount');
requireInstance(amount, TemporalAmount, 'amount');
return amount.addTo(this);
}
/**
* Returns an object of the same type as this object with the specified period added.
* This method returns a new object based on this one with the specified period added. For example, on a {@link LocalDate}, this could be used to add a number of years, months or days. The returned object will have the same observable type as this object.
*
* In some cases, changing a field is not fully defined. For example, if the target object is a date representing the 31st January, then adding one month would be unclear. In cases like this, the field is responsible for resolving the result. Typically it will choose the previous valid date, which would be the last valid day of February in this example.
*
* If the implementation represents a date-time that has boundaries, such as {@link LocalTime}, then the permitted units must include the boundary unit, but no multiples of the boundary unit. For example, {@link LocalTime} must accept `DAYS` but not `WEEKS` or `MONTHS`.
*
* ### Specification for implementors
* Implementations must check and handle all units defined in {@link ChronoUnit}. If the unit is supported, then the addition must be performed. If unsupported, then a {@link DateTimeException} must be thrown.
* If the unit is not a {@link ChronoUnit}, then the result of this method is obtained by invoking `TemporalUnit.addTo(Temporal, long)` passing this as the first argument.
*
* Implementations must not alter either this object or the specified temporal object. Instead, an adjusted copy of the original must be returned. This provides equivalent, safe behavior for immutable and mutable implementations.
*
* @param {number} amountToAdd - the amount of the specified unit to add, may be negative
* @param {TemporalUnit} unit - the unit of the period to add, not null
* @return {Temporal} an object of the same type with the specified period added, not null
* @throws DateTimeException - if the unit cannot be added
* @throws ArithmeticException - if numeric overflow occurs
*/
// eslint-disable-next-line no-unused-vars
_plusUnit(amountToAdd, unit) {
abstractMethodFail('_plusUnit');
}
/**
* Calculates the period between this temporal and another temporal in terms of the specified unit.
* This calculates the period between two temporals in terms of a single unit. The start and end points are this and the specified temporal. The result will be negative if the end is before the start. For example, the period in hours between two temporal objects can be calculated using `startTime.until(endTime, HOURS)`.
*
* The calculation returns a whole number, representing the number of complete units between the two temporals. For example, the period in hours between the times 11:30 and 13:29 will only be one hour as it is one minute short of two hours.
*
* There are two equivalent ways of using this method. The first is to invoke this method directly. The second is to use `TemporalUnit.between(Temporal, Temporal)`:
*
* <pre>
* // these two lines are equivalent
* between = thisUnit.between(start, end);
* between = start.until(end, thisUnit);
* </pre>
*
* The choice should be made based on which makes the code more readable.
* For example, this method allows the number of days between two dates to be calculated:
*
* <pre>
* long daysBetween = DAYS.between(start, end);
* // or alternatively
* long daysBetween = start.until(end, DAYS);
* </pre>
*
* ### Specification for implementors
* Implementations must begin by checking to ensure that the input temporal object is of the same observable type as the implementation. They must then perform the calculation for all instances of {@link ChronoUnit}. A {@link DateTimeException} must be thrown for {@link ChronoUnit} instances that are unsupported.
* If the unit is not a {@link ChronoUnit}, then the result of this method is obtained by invoking `TemporalUnit.between(Temporal, Temporal)` passing this as the first argument and the input temporal as the second argument.
*
* In summary, implementations must behave in a manner equivalent to this code:
*
* <pre>
* // check input temporal is the same type as this class
* if (unit instanceof ChronoUnit) {
* // if unit is supported, then calculate and return result
* // else throw DateTimeException for unsupported units
* }
* return unit.between(this, endTemporal);
* </pre>
*
* The target object must not be altered by this method.
*
* @param {Temporal} endTemporal - the end temporal, of the same type as this object, not null
* @param {TemporalUnit} unit - the unit to measure the period in, not null
* @return {number} the amount of the period between this and the end
* @throws DateTimeException - if the period cannot be calculated
* @throws ArithmeticException - if numeric overflow occurs
*/
// eslint-disable-next-line no-unused-vars
until(endTemporal, unit) {
abstractMethodFail('until');
}
/**
* function overloading for {@link Temporal.with}
*
* Called with 1 (or less) arguments, p1 is expected to be a {@link TemporalAdjuster} and {@link Temporal.withAdjuster} is called.
*
* Otherwise {@link Temporal.withFieldValue} is called.
*
* @param {!(TemporalAdjuster|TemporalField)} adjusterOrField
* @param {number} newValue
* @return {Temporal}
*/
with(adjusterOrField, newValue) {
if (arguments.length < 2) {
return this._withAdjuster(adjusterOrField);
} else {
return this._withField(adjusterOrField, newValue);
}
}
/**
* Returns an adjusted object of the same type as this object with the adjustment made.
* This adjusts this date-time according to the rules of the specified adjuster. A simple adjuster might simply set the one of the fields, such as the year field. A more complex adjuster might set the date to the last day of the month. A selection of common adjustments is provided in {@link TemporalAdjusters}. These include finding the "last day of the month" and "next Wednesday". The adjuster is responsible for handling special cases, such as the varying lengths of month and leap years.
*
* Some example code indicating how and why this method is used:
*
* <pre>
* date = date.with(Month.JULY); // most key classes implement TemporalAdjuster
* date = date.with(lastDayOfMonth()); // static import from TemporalAdjusters
* date = date.with(next(WEDNESDAY)); // static import from TemporalAdjusters and DayOfWeek
* </pre>
*
* ### Specification for implementors
* Implementations must not alter either this object. Instead, an adjusted copy of the original must be returned. This provides equivalent, safe behavior for immutable and mutable implementations.
*
* @param {TemporalAdjuster} adjuster - the adjuster to use, not null
* @return {Temporal} an object of the same type with the specified adjustment made, not null
* @throws DateTimeException - if unable to make the adjustment
* @throws ArithmeticException - if numeric overflow occurs
*/
_withAdjuster(adjuster) {
requireNonNull(adjuster, 'adjuster');
assert(typeof adjuster.adjustInto === 'function',
'adjuster must be a TemporalAdjuster',
IllegalArgumentException);
return adjuster.adjustInto(this);
}
/**
* Returns an object of the same type as this object with the specified field altered.
* This returns a new object based on this one with the value for the specified field changed. For example, on a {@link LocalDate}, this could be used to set the year, month or day-of-month. The returned object will have the same observable type as this object.
*
* In some cases, changing a field is not fully defined. For example, if the target object is a date representing the 31st January, then changing the month to February would be unclear. In cases like this, the field is responsible for resolving the result. Typically it will choose the previous valid date, which would be the last valid day of February in this example.
*
* ### Specification for implementors
* Implementations must check and handle all fields defined in {@link ChronoField}. If the field is supported, then the adjustment must be performed. If unsupported, then a {@link DateTimeException} must be thrown.
* If the field is not a {@link ChronoField}, then the result of this method is obtained by invoking `TemporalField.adjustInto(Temporal, long)` passing this as the first argument.
*
* Implementations must not alter either this object or the specified temporal object. Instead, an adjusted copy of the original must be returned. This provides equivalent, safe behavior for immutable and mutable implementations.
*
* @param {TemporalField} field - the field to set in the result, not null
* @param {number} newValue - the new value of the field in the result
* @return {Temporal} an object of the same type with the specified field set, not null
* @throws DateTimeException - if the field cannot be set
* @throws ArithmeticException - if numeric overflow occurs
*/
// eslint-disable-next-line no-unused-vars
_withField(field, newValue) {
abstractMethodFail('_withField');
}
}
if (typeof Symbol !== 'undefined' && Symbol.toPrimitive) {
Temporal.prototype[Symbol.toPrimitive] = function (hint) {
// hint could be 'number', 'string' or 'default'. Only 'number'
// should throw and 'default' is treated as 'string'.
if (hint !== 'number') {
return this.toString();
}
throw new TypeError(
'A conversion from Temporal to a number is not allowed. ' +
'To compare use the methods .equals(), .compareTo(), .isBefore() ' +
'or one that is more suitable to your use case.'
);
};
}

View File

@@ -0,0 +1,135 @@
/**
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
import { UnsupportedTemporalTypeException } from '../errors';
import { abstractMethodFail } from '../assert';
import { ChronoField } from './ChronoField';
import { TemporalQueries } from './TemporalQueries';
export class TemporalAccessor {
/**
* Queries this date-time.
*
* This queries this date-time using the specified query strategy object.
*
* Queries are a key tool for extracting information from date-times.
* They exists to externalize the process of querying, permitting different
* approaches, as per the strategy design pattern.
* Examples might be a query that checks if the date is the day before February 29th
* in a leap year, or calculates the number of days to your next birthday.
*
* The most common query implementations are method references, such as
* {@link LocalDate::from} and {@link ZoneId::from}.
* Further implementations are on {@link TemporalQueries}.
* Queries may also be defined by applications.
*
* @implSpec
* Implementations of this method must behave as follows:
* <pre>
if (query == TemporalQueries.zoneId()
|| query == TemporalQueries.chronology()
|| query == TemporalQueries.precision()) {
return null;
}
return query.queryFrom(this);
* </pre>
*
* @param {TemporalQuery} query the query to invoke, not null
* @return the query result, null may be returned (defined by the query)
* @throws DateTimeException if unable to query
* @throws ArithmeticException if numeric overflow occurs
*/
query(query) {
if (query === TemporalQueries.zoneId()
|| query === TemporalQueries.chronology()
|| query === TemporalQueries.precision()) {
return null;
}
return query.queryFrom(this);
}
/**
* Gets the value of the specified field as an `int`.
*
* This queries the date-time for the value for the specified field.
* The returned value will always be within the valid range of values for the field.
* If the date-time cannot return the value, because the field is unsupported or for
* some other reason, an exception will be thrown.
*
* ### Specification for implementors
*
* Implementations must check and handle all fields defined in {@link ChronoField}.
* If the field is supported and has an `int` range, then the value of
* the field must be returned.
* If unsupported, then a {@link DateTimeException} must be thrown.
*
* If the field is not a {@link ChronoField}, then the result of this method
* is obtained by invoking {@link TemporalField.getFrom}
* passing `this` as the argument.
*
* Implementations must not alter either this object.
*
* @param {TemporalField} field - the field to get, not null
* @return {number} the value for the field, within the valid range of values
* @throws DateTimeException if a value for the field cannot be obtained
* @throws DateTimeException if the range of valid values for the field exceeds an `int`
* @throws DateTimeException if the value is outside the range of valid values for the field
* @throws ArithmeticException if numeric overflow occurs
*/
get(field) {
return this.range(field).checkValidIntValue(this.getLong(field), field);
}
// eslint-disable-next-line no-unused-vars
getLong(field) {
abstractMethodFail('getLong');
}
/**
* Gets the range of valid values for the specified field.
*
* All fields can be expressed as a `long` integer.
* This method returns an object that describes the valid range for that value.
* The value of this temporal object is used to enhance the accuracy of the returned range.
* If the date-time cannot return the range, because the field is unsupported or for
* some other reason, an exception will be thrown.
*
* Note that the result only describes the minimum and maximum valid values
* and it is important not to read too much into them. For example, there
* could be values within the range that are invalid for the field.
*
* ### Specification for implementors
*
* Implementations must check and handle all fields defined in {@link ChronoField}.
* If the field is supported, then the range of the field must be returned.
* If unsupported, then a {@link DateTimeException} must be thrown.
*
* If the field is not a {@link ChronoField}, then the result of this method
* is obtained by invoking {@link TemporalField.rangeRefinedBy}
* passing `this` as the argument.
*
* Implementations must not alter either this object.
*
* @param {TemporalField} field the field to query the range for, not null
* @return {ValueRange} the range of valid values for the field, not null
* @throws DateTimeException if the range for the field cannot be obtained
*/
range(field) {
if (field instanceof ChronoField) {
if (this.isSupported(field)) {
return field.range();
}
throw new UnsupportedTemporalTypeException(`Unsupported field: ${field}`);
}
return field.rangeRefinedBy(this);
}
// eslint-disable-next-line no-unused-vars
isSupported(field) {
abstractMethodFail('isSupported');
}
}

View File

@@ -0,0 +1,92 @@
/*
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
import { abstractMethodFail } from '../assert';
/**
* Strategy for adjusting a temporal object.
*
* Adjusters are a key tool for modifying temporal objects.
* They exist to externalize the process of adjustment, permitting different
* approaches, as per the strategy design pattern.
* Examples might be an adjuster that sets the date avoiding weekends, or one that
* sets the date to the last day of the month.
*
* There are two equivalent ways of using a {@link TemporalAdjuster}.
* The first is to invoke the method on this interface directly.
* The second is to use {@link Temporal#with}:
* <pre>
* // these two lines are equivalent, but the second approach is recommended
* temporal = thisAdjuster.adjustInto(temporal);
* temporal = temporal.with(thisAdjuster);
* </pre>
* It is recommended to use the second approach, {@link with},
* as it is a lot clearer to read in code.
*
* See {@link TemporalAdjusters} for a standard set of adjusters, including finding the
* last day of the month.
* Adjusters may also be defined by applications.
*
* ### Specification for implementors
*
* This interface places no restrictions on the mutability of implementations,
* however immutability is strongly recommended.
*
* @interface
*/
export class TemporalAdjuster {
/**
* Adjusts the specified temporal object.
*
* This adjusts the specified temporal object using the logic
* encapsulated in the implementing class.
* Examples might be an adjuster that sets the date avoiding weekends, or one that
* sets the date to the last day of the month.
*
* There are two equivalent ways of using this method.
* The first is to invoke this method directly.
* The second is to use {@link Temporal#with}:
* <pre>
* // these two lines are equivalent, but the second approach is recommended
* temporal = thisAdjuster.adjustInto(temporal);
* temporal = temporal.with(thisAdjuster);
* </pre>
* It is recommended to use the second approach, {@link with},
* as it is a lot clearer to read in code.
*
* ### Specification for implementors
*
* The implementation must take the input object and adjust it.
* The implementation defines the logic of the adjustment and is responsible for
* documenting that logic. It may use any method on {@link Temporal} to
* query the temporal object and perform the adjustment.
* The returned object must have the same observable type as the input object
*
* The input object must not be altered.
* Instead, an adjusted copy of the original must be returned.
* This provides equivalent, safe behavior for immutable and mutable temporal objects.
*
* The input temporal object may be in a calendar system other than ISO.
* Implementations may choose to document compatibility with other calendar systems,
* or reject non-ISO temporal objects by querying the chronology (see {@link TemporalQueries#chronology}).
*
* This method may be called from multiple threads in parallel.
* It must be thread-safe when invoked.
*
* @param {Temporal} temporal the temporal object to adjust, not null
* @return {Temporal} an object of the same observable type with the adjustment made, not null
* @throws DateTimeException if unable to make the adjustment
* @throws ArithmeticException if numeric overflow occurs
*
* @abstract
*/
// eslint-disable-next-line no-unused-vars
adjustInto(temporal){
abstractMethodFail('adjustInto');
}
}

View File

@@ -0,0 +1,464 @@
/*
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
import { requireNonNull } from '../assert';
import { IllegalStateException } from '../errors';
import { TemporalAdjuster } from './TemporalAdjuster';
import { ChronoField } from '../temporal/ChronoField';
import { ChronoUnit } from '../temporal/ChronoUnit';
import { MathUtil } from '../MathUtil';
/**
* Common implementations of {@link TemporalAdjuster}.
*
* This class provides common implementations of {@link TemporalAdjuster}.
* They are especially useful to document the intent of business logic and
* often link well to requirements.
* For example, these two pieces of code do the same thing, but the second
* one is clearer (assuming that there is a static import of this class):
* <pre>
* // direct manipulation
* date.withDayOfMonth(1).plusMonths(1).minusDays(1);
* // use of an adjuster from this class
* date.with(lastDayOfMonth());
* </pre>
* There are two equivalent ways of using a {@link TemporalAdjuster}.
* The first is to invoke the method on the interface directly.
* The second is to use {@link Temporal#with}:
* <pre>
* // these two lines are equivalent, but the second approach is recommended
* dateTime = adjuster.adjustInto(dateTime);
* dateTime = dateTime.with(adjuster);
* </pre>
* It is recommended to use the second approach, {@link with},
* as it is a lot clearer to read in code.
*
* ### Specification for implementors
*
* This is a thread-safe utility class.
* All returned adjusters are immutable and thread-safe.
*
* The JDK 8 ofDateAdjuster(UnaryOperator) method is not backported.
*/
export class TemporalAdjusters {
//-----------------------------------------------------------------------
/**
* Returns the 'first day of month' adjuster, which returns a new date set to
* the first day of the current month.
*
* The ISO calendar system behaves as follows:
*
* * The input 2011-01-15 will return 2011-01-01.
* * The input 2011-02-15 will return 2011-02-01.
*
* The behavior is suitable for use with most calendar systems.
* It is equivalent to:
* <pre>
* temporal.with(DAY_OF_MONTH, 1);
* </pre>
*
* @return {TemporalAdjuster} the first day-of-month adjuster, not null
*/
static firstDayOfMonth() {
return Impl.FIRST_DAY_OF_MONTH;
}
/**
* Returns the 'last day of month' adjuster, which returns a new date set to
* the last day of the current month.
*
* The ISO calendar system behaves as follows:
*
* * The input 2011-01-15 will return 2011-01-31.
* * The input 2011-02-15 will return 2011-02-28.
* * The input 2012-02-15 will return 2012-02-29 (leap year).
* * The input 2011-04-15 will return 2011-04-30.
*
* The behavior is suitable for use with most calendar systems.
* It is equivalent to:
* <pre>
* long lastDay = temporal.range(DAY_OF_MONTH).getMaximum();
* temporal.with(DAY_OF_MONTH, lastDay);
* </pre>
*
* @return {TemporalAdjuster} the last day-of-month adjuster, not null
*/
static lastDayOfMonth() {
return Impl.LAST_DAY_OF_MONTH;
}
/**
* Returns the 'first day of next month' adjuster, which returns a new date set to
* the first day of the next month.
*
* The ISO calendar system behaves as follows:
*
* * The input 2011-01-15 will return 2011-02-01.
* * The input 2011-02-15 will return 2011-03-01.
*
* The behavior is suitable for use with most calendar systems.
* It is equivalent to:
* <pre>
* temporal.with(DAY_OF_MONTH, 1).plus(1, MONTHS);
* </pre>
*
* @return {TemporalAdjuster} the first day of next month adjuster, not null
*/
static firstDayOfNextMonth() {
return Impl.FIRST_DAY_OF_NEXT_MONTH;
}
//-----------------------------------------------------------------------
/**
* Returns the 'first day of year' adjuster, which returns a new date set to
* the first day of the current year.
*
* The ISO calendar system behaves as follows:
*
* * The input 2011-01-15 will return 2011-01-01.
* * The input 2011-02-15 will return 2011-01-01.
*
* The behavior is suitable for use with most calendar systems.
* It is equivalent to:
* <pre>
* temporal.with(DAY_OF_YEAR, 1);
* </pre>
*
* @return {TemporalAdjuster} the first day-of-year adjuster, not null
*/
static firstDayOfYear() {
return Impl.FIRST_DAY_OF_YEAR;
}
/**
* Returns the 'last day of year' adjuster, which returns a new date set to
* the last day of the current year.
*
* The ISO calendar system behaves as follows:
*
* * The input 2011-01-15 will return 2011-12-31.
* * The input 2011-02-15 will return 2011-12-31.
*
* The behavior is suitable for use with most calendar systems.
* It is equivalent to:
* <pre>
* long lastDay = temporal.range(DAY_OF_YEAR).getMaximum();
* temporal.with(DAY_OF_YEAR, lastDay);
* </pre>
*
* @return {TemporalAdjuster} the last day-of-year adjuster, not null
*/
static lastDayOfYear() {
return Impl.LAST_DAY_OF_YEAR;
}
/**
* Returns the 'first day of next year' adjuster, which returns a new date set to
* the first day of the next year.
*
* The ISO calendar system behaves as follows:
*
* * The input 2011-01-15 will return 2012-01-01.
*
* The behavior is suitable for use with most calendar systems.
* It is equivalent to:
* <pre>
* temporal.with(DAY_OF_YEAR, 1).plus(1, YEARS);
* </pre>
*
* @return {TemporalAdjuster} the first day of next month adjuster, not null
*/
static firstDayOfNextYear() {
return Impl.FIRST_DAY_OF_NEXT_YEAR;
}
//-----------------------------------------------------------------------
/**
* Returns the first in month adjuster, which returns a new date
* in the same month with the first matching day-of-week.
* This is used for expressions like 'first Tuesday in March'.
*
* The ISO calendar system behaves as follows:
*
* * The input 2011-12-15 for (MONDAY) will return 2011-12-05.
* * The input 2011-12-15 for (FRIDAY) will return 2011-12-02.
*
* The behavior is suitable for use with most calendar systems.
* It uses the {@link DAY_OF_WEEK} and {@link DAY_OF_MONTH} fields
* and the {@link DAYS} unit, and assumes a seven day week.
*
* @param {DayOfWeek} dayOfWeek the day-of-week, not null
* @return {TemporalAdjuster} the first in month adjuster, not null
*/
static firstInMonth(dayOfWeek) {
requireNonNull(dayOfWeek, 'dayOfWeek');
return new DayOfWeekInMonth(1, dayOfWeek);
}
/**
* Returns the last in month adjuster, which returns a new date
* in the same month with the last matching day-of-week.
* This is used for expressions like 'last Tuesday in March'.
*
* The ISO calendar system behaves as follows:
*
* * The input 2011-12-15 for (MONDAY) will return 2011-12-26.
* * The input 2011-12-15 for (FRIDAY) will return 2011-12-30.
*
* The behavior is suitable for use with most calendar systems.
* It uses the {@link DAY_OF_WEEK} and {@link DAY_OF_MONTH} fields
* and the {@link DAYS} unit, and assumes a seven day week.
*
* @param {DayOfWeek} dayOfWeek the day-of-week, not null
* @return {TemporalAdjuster} the first in month adjuster, not null
*/
static lastInMonth(dayOfWeek) {
requireNonNull(dayOfWeek, 'dayOfWeek');
return new DayOfWeekInMonth(-1, dayOfWeek);
}
/**
* Returns the day-of-week in month adjuster, which returns a new date
* in the same month with the ordinal day-of-week.
* This is used for expressions like the 'second Tuesday in March'.
*
* The ISO calendar system behaves as follows:
*
* * The input 2011-12-15 for (1,TUESDAY) will return 2011-12-06.
* * The input 2011-12-15 for (2,TUESDAY) will return 2011-12-13.
* * The input 2011-12-15 for (3,TUESDAY) will return 2011-12-20.
* * The input 2011-12-15 for (4,TUESDAY) will return 2011-12-27.
* * The input 2011-12-15 for (5,TUESDAY) will return 2012-01-03.
* * The input 2011-12-15 for (-1,TUESDAY) will return 2011-12-27 (last in month).
* * The input 2011-12-15 for (-4,TUESDAY) will return 2011-12-06 (3 weeks before last in month).
* * The input 2011-12-15 for (-5,TUESDAY) will return 2011-11-29 (4 weeks before last in month).
* * The input 2011-12-15 for (0,TUESDAY) will return 2011-11-29 (last in previous month).
*
* For a positive or zero ordinal, the algorithm is equivalent to finding the first
* day-of-week that matches within the month and then adding a number of weeks to it.
* For a negative ordinal, the algorithm is equivalent to finding the last
* day-of-week that matches within the month and then subtracting a number of weeks to it.
* The ordinal number of weeks is not validated and is interpreted leniently
* according to this algorithm. This definition means that an ordinal of zero finds
* the last matching day-of-week in the previous month.
*
* The behavior is suitable for use with most calendar systems.
* It uses the {@link DAY_OF_WEEK} and {@link DAY_OF_MONTH} fields
* and the {@link DAYS} unit, and assumes a seven day week.
*
* @param {Number} ordinal the week within the month, unbounded but typically from -5 to 5
* @param {DayOfWeek} dayOfWeek the day-of-week, not null
* @return {TemporalAdjuster} the day-of-week in month adjuster, not null
*/
static dayOfWeekInMonth(ordinal, dayOfWeek) {
requireNonNull(dayOfWeek, 'dayOfWeek');
return new DayOfWeekInMonth(ordinal, dayOfWeek);
}
//-----------------------------------------------------------------------
/**
* Returns the next day-of-week adjuster, which adjusts the date to the
* first occurrence of the specified day-of-week after the date being adjusted.
*
* The ISO calendar system behaves as follows:
*
* * The input 2011-01-15 (a Saturday) for parameter (MONDAY) will return 2011-01-17 (two days later).
* * The input 2011-01-15 (a Saturday) for parameter (WEDNESDAY) will return 2011-01-19 (four days later).
* * The input 2011-01-15 (a Saturday) for parameter (SATURDAY) will return 2011-01-22 (seven days later).
*
* The behavior is suitable for use with most calendar systems.
* It uses the {@link DAY_OF_WEEK} field and the {@link DAYS} unit,
* and assumes a seven day week.
*
* @param {DayOfWeek} dayOfWeek the day-of-week to move the date to, not null
* @return {TemporalAdjuster} the next day-of-week adjuster, not null
*/
static next(dayOfWeek) {
return new RelativeDayOfWeek(2, dayOfWeek);
}
/**
* Returns the next-or-same day-of-week adjuster, which adjusts the date to the
* first occurrence of the specified day-of-week after the date being adjusted
* unless it is already on that day in which case the same object is returned.
*
* The ISO calendar system behaves as follows:
*
* * The input 2011-01-15 (a Saturday) for parameter (MONDAY) will return 2011-01-17 (two days later).
* * The input 2011-01-15 (a Saturday) for parameter (WEDNESDAY) will return 2011-01-19 (four days later).
* * The input 2011-01-15 (a Saturday) for parameter (SATURDAY) will return 2011-01-15 (same as input).
*
* The behavior is suitable for use with most calendar systems.
* It uses the {@link DAY_OF_WEEK} field and the {@link DAYS} unit,
* and assumes a seven day week.
*
* @param {DayOfWeek} dayOfWeek the day-of-week to check for or move the date to, not null
* @return {TemporalAdjuster} the next-or-same day-of-week adjuster, not null
*/
static nextOrSame(dayOfWeek) {
return new RelativeDayOfWeek(0, dayOfWeek);
}
/**
* Returns the previous day-of-week adjuster, which adjusts the date to the
* first occurrence of the specified day-of-week before the date being adjusted.
*
* The ISO calendar system behaves as follows:
*
* * The input 2011-01-15 (a Saturday) for parameter (MONDAY) will return 2011-01-10 (five days earlier).
* * The input 2011-01-15 (a Saturday) for parameter (WEDNESDAY) will return 2011-01-12 (three days earlier).
* * The input 2011-01-15 (a Saturday) for parameter (SATURDAY) will return 2011-01-08 (seven days earlier).
*
* The behavior is suitable for use with most calendar systems.
* It uses the {@link DAY_OF_WEEK} field and the {@link DAYS} unit,
* and assumes a seven day week.
*
* @param {DayOfWeek} dayOfWeek the day-of-week to move the date to, not null
* @return {TemporalAdjuster} the previous day-of-week adjuster, not null
*/
static previous(dayOfWeek) {
return new RelativeDayOfWeek(3, dayOfWeek);
}
/**
* Returns the previous-or-same day-of-week adjuster, which adjusts the date to the
* first occurrence of the specified day-of-week before the date being adjusted
* unless it is already on that day in which case the same object is returned.
*
* The ISO calendar system behaves as follows:
*
* * The input 2011-01-15 (a Saturday) for parameter (MONDAY) will return 2011-01-10 (five days earlier).
* * The input 2011-01-15 (a Saturday) for parameter (WEDNESDAY) will return 2011-01-12 (three days earlier).
* * The input 2011-01-15 (a Saturday) for parameter (SATURDAY) will return 2011-01-15 (same as input).
*
* The behavior is suitable for use with most calendar systems.
* It uses the {@link DAY_OF_WEEK} field and the {@link DAYS} unit,
* and assumes a seven day week.
*
* @param {DayOfWeek} dayOfWeek the day-of-week to check for or move the date to, not null
* @return {TemporalAdjuster} the previous-or-same day-of-week adjuster, not null
*/
static previousOrSame(dayOfWeek) {
return new RelativeDayOfWeek(1, dayOfWeek);
}
}
//-----------------------------------------------------------------------
/**
* Enum implementing the adjusters.
*/
class Impl extends TemporalAdjuster {
/**
*
* @param ordinal
* @private
*/
constructor(ordinal) {
super();
this._ordinal = ordinal;
}
adjustInto(temporal) {
switch (this._ordinal) {
case 0: return temporal.with(ChronoField.DAY_OF_MONTH, 1);
case 1: return temporal.with(ChronoField.DAY_OF_MONTH, temporal.range(ChronoField.DAY_OF_MONTH).maximum());
case 2: return temporal.with(ChronoField.DAY_OF_MONTH, 1).plus(1, ChronoUnit.MONTHS);
case 3: return temporal.with(ChronoField.DAY_OF_YEAR, 1);
case 4: return temporal.with(ChronoField.DAY_OF_YEAR, temporal.range(ChronoField.DAY_OF_YEAR).maximum());
case 5: return temporal.with(ChronoField.DAY_OF_YEAR, 1).plus(1, ChronoUnit.YEARS);
}
throw new IllegalStateException('Unreachable');
}
}
/** First day of month adjuster. */
Impl.FIRST_DAY_OF_MONTH = new Impl(0);
/** Last day of month adjuster. */
Impl.LAST_DAY_OF_MONTH = new Impl(1);
/** First day of next month adjuster. */
Impl.FIRST_DAY_OF_NEXT_MONTH = new Impl(2);
/** First day of year adjuster. */
Impl.FIRST_DAY_OF_YEAR = new Impl(3);
/** Last day of year adjuster. */
Impl.LAST_DAY_OF_YEAR = new Impl(4);
/** First day of next month adjuster. */
Impl.FIRST_DAY_OF_NEXT_YEAR = new Impl(5);
/**
* Class implementing day-of-week in month adjuster.
*/
class DayOfWeekInMonth extends TemporalAdjuster {
/**
*
* @param ordinal
* @param dow
* @private
*/
constructor(ordinal, dow) {
super();
this._ordinal = ordinal;
this._dowValue = dow.value();
}
adjustInto(temporal) {
if (this._ordinal >= 0) {
const temp = temporal.with(ChronoField.DAY_OF_MONTH, 1);
const curDow = temp.get(ChronoField.DAY_OF_WEEK);
let dowDiff = MathUtil.intMod((this._dowValue - curDow + 7), 7);
dowDiff += (this._ordinal - 1) * 7; // safe from overflow
return temp.plus(dowDiff, ChronoUnit.DAYS);
} else {
const temp = temporal.with(ChronoField.DAY_OF_MONTH, temporal.range(ChronoField.DAY_OF_MONTH).maximum());
const curDow = temp.get(ChronoField.DAY_OF_WEEK);
let daysDiff = this._dowValue - curDow;
daysDiff = (daysDiff === 0 ? 0 : (daysDiff > 0 ? daysDiff - 7 : daysDiff));
daysDiff -= (-this._ordinal - 1) * 7; // safe from overflow
return temp.plus(daysDiff, ChronoUnit.DAYS);
}
}
}
/**
* Implementation of next, previous or current day-of-week.
*/
class RelativeDayOfWeek extends TemporalAdjuster {
/**
*
* @param relative
* @param dayOfWeek
* @private
*/
constructor(relative, dayOfWeek) {
super();
requireNonNull(dayOfWeek, 'dayOfWeek');
/** Whether the current date is a valid answer. */
this._relative = relative;
/** The day-of-week value, from 1 to 7. */
this._dowValue = dayOfWeek.value();
}
adjustInto(temporal) {
const calDow = temporal.get(ChronoField.DAY_OF_WEEK);
if (this._relative < 2 && calDow === this._dowValue) {
return temporal;
}
if ((this._relative & 1) === 0) {
const daysDiff = calDow - this._dowValue;
return temporal.plus(daysDiff >= 0 ? 7 - daysDiff : -daysDiff, ChronoUnit.DAYS);
} else {
const daysDiff = this._dowValue - calDow;
return temporal.minus(daysDiff >= 0 ? 7 - daysDiff : -daysDiff, ChronoUnit.DAYS);
}
}
}

View File

@@ -0,0 +1,182 @@
/*
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
import { abstractMethodFail } from '../assert';
/**
* Framework-level interface defining an amount of time, such as
* "6 hours", "8 days" or "2 years and 3 months".
*
* This is the base interface type for amounts of time.
* An amount is distinct from a date or time-of-day in that it is not tied
* to any specific point on the time-line.
*
* The amount can be thought of as a {@link Map} of {@link TemporalUnit} to
* `long`, exposed via {@link getUnits} and {@link get}.
* A simple case might have a single unit-value pair, such as "6 hours".
* A more complex case may have multiple unit-value pairs, such as
* "7 years, 3 months and 5 days".
*
* There are two common implementations.
* {@link Period} is a date-based implementation, storing years, months and days.
* {@link Duration} is a time-based implementation, storing seconds and nanoseconds,
* but providing some access using other duration based units such as minutes,
* hours and fixed 24-hour days.
*
* This interface is a framework-level interface that should not be widely
* used in application code. Instead, applications should create and pass
* around instances of concrete types, such as {@link Period} and {@link Duration}.
*
* @interface
*/
export class TemporalAmount {
/**
* Returns the value of the requested unit.
* The units returned from {@link getUnits} uniquely define the
* value of the {@link TemporalAmount}. A value must be returned
* for each unit listed in {@link getUnits}.
*
* @implSpec
* Implementations may declare support for units not listed by {@link getUnits}.
* Typically, the implementation would define additional units
* as conversions for the convenience of developers.
*
* @param {TemporalUnit} unit - the {@link TemporalUnit} for which to return the value
* @return {number} the long value of the unit
* @throws DateTimeException if a value for the unit cannot be obtained
* @throws UnsupportedTemporalTypeException if the {@link unit} is not supported
*/
// eslint-disable-next-line no-unused-vars
get(unit) {
abstractMethodFail('get');
}
/**
* Returns the list of units uniquely defining the value of this TemporalAmount.
* The list of {@link TemporalUnits} is defined by the implementation class.
* The list is a snapshot of the units at the time {@link getUnits}
* is called and is not mutable.
* The units are ordered from longest duration to the shortest duration
* of the unit.
*
* @implSpec
* The list of units completely and uniquely represents the
* state of the object without omissions, overlaps or duplication.
* The units are in order from longest duration to shortest.
*
* @return {TemporalUnit[]} the List of {@link TemporalUnits}; not null
*/
units() {
abstractMethodFail('units');
}
/**
* Adds to the specified temporal object.
*
* Adds the amount to the specified temporal object using the logic
* encapsulated in the implementing class.
*
* There are two equivalent ways of using this method.
* The first is to invoke this method directly.
* The second is to use {@link Temporal#plus}:
* <pre>
* // These two lines are equivalent, but the second approach is recommended
* dateTime = amount.addTo(dateTime);
* dateTime = dateTime.plus(adder);
* </pre>
* It is recommended to use the second approach, {@link plus},
* as it is a lot clearer to read in code.
*
* @implSpec
* The implementation must take the input object and add to it.
* The implementation defines the logic of the addition and is responsible for
* documenting that logic. It may use any method on {@link Temporal} to
* query the temporal object and perform the addition.
* The returned object must have the same observable type as the input object
*
* The input object must not be altered.
* Instead, an adjusted copy of the original must be returned.
* This provides equivalent, safe behavior for immutable and mutable temporal objects.
*
* The input temporal object may be in a calendar system other than ISO.
* Implementations may choose to document compatibility with other calendar systems,
* or reject non-ISO temporal objects by querying the chronology (see {@link TemporalQueries#chronology}).
*
* This method may be called from multiple threads in parallel.
* It must be thread-safe when invoked.
*
* @param {Temporal} temporal - the temporal object to add the amount to, not null
* @return {Temporal} an object of the same observable type with the addition made, not null
* @throws DateTimeException if unable to add
* @throws ArithmeticException if numeric overflow occurs
*/
// eslint-disable-next-line no-unused-vars
addTo(temporal) {
abstractMethodFail('addTo');
}
/**
* Subtracts this object from the specified temporal object.
*
* Subtracts the amount from the specified temporal object using the logic
* encapsulated in the implementing class.
*
* There are two equivalent ways of using this method.
* The first is to invoke this method directly.
* The second is to use {@link Temporal#minus}:
* <pre>
* // these two lines are equivalent, but the second approach is recommended
* dateTime = amount.subtractFrom(dateTime);
* dateTime = dateTime.minus(amount);
* </pre>
* It is recommended to use the second approach, {@link minus},
* as it is a lot clearer to read in code.
*
* @implSpec
* The implementation must take the input object and subtract from it.
* The implementation defines the logic of the subtraction and is responsible for
* documenting that logic. It may use any method on {@link Temporal} to
* query the temporal object and perform the subtraction.
* The returned object must have the same observable type as the input object
*
* The input object must not be altered.
* Instead, an adjusted copy of the original must be returned.
* This provides equivalent, safe behavior for immutable and mutable temporal objects.
*
* The input temporal object may be in a calendar system other than ISO.
* Implementations may choose to document compatibility with other calendar systems,
* or reject non-ISO temporal objects by querying the chronology (see {@link TemporalQueries#chronology}).
*
* This method may be called from multiple threads in parallel.
* It must be thread-safe when invoked.
*
* @param {Temporal} temporal - the temporal object to subtract the amount from, not null
* @return {Temporal} an object of the same observable type with the subtraction made, not null
* @throws DateTimeException if unable to subtract
* @throws ArithmeticException if numeric overflow occurs
*/
// eslint-disable-next-line no-unused-vars
subtractFrom(temporal) {
abstractMethodFail('subtractFrom');
}
}
if (typeof Symbol !== 'undefined' && Symbol.toPrimitive) {
TemporalAmount.prototype[Symbol.toPrimitive] = function (hint) {
// hint could be 'number', 'string' or 'default'. Only 'number'
// should throw and 'default' is treated as 'string'.
if (hint !== 'number') {
return this.toString();
}
throw new TypeError(
'A conversion from TemporalAmount to a number is not allowed. ' +
'To compare use the methods .equals(), .compareTo(), .isBefore() ' +
'or one that is more suitable to your use case.'
);
};
}

View File

@@ -0,0 +1,248 @@
import { abstractMethodFail } from '../assert';
/**
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
/**
* A field of date-time, such as month-of-year or hour-of-minute.
*
* Date and time is expressed using fields which partition the time-line into something
* meaningful for humans. Implementations of this interface represent those fields.
*
* The most commonly used units are defined in {@link ChronoField}.
* Further fields are supplied in {@link IsoFields}, {@link WeekFields} and {@link JulianFields}.
* Fields can also be written by application code by implementing this interface.
*
* The field works using double dispatch. Client code calls methods on a date-time like
* {@link LocalDateTime} which check if the field is a {@link ChronoField}.
* If it is, then the date-time must handle it.
* Otherwise, the method call is re-dispatched to the matching method in this interface.
*
* @interface
*/
export class TemporalField {
/**
* Checks if this field represents a component of a date.
*
* @return {boolean} `true` if it is a component of a date, `false` otherwise.
*/
isDateBased() {
abstractMethodFail('isDateBased');
}
/**
* Checks if this field represents a component of a time.
*
* @return {boolean} `true` if it is a component of a time, `false` otherwise.
*/
isTimeBased() {
abstractMethodFail('isTimeBased');
}
/**
* Gets the unit that the field is measured in.
*
* The unit of the field is the period that varies within the range.
* For example, in the field 'MonthOfYear', the unit is 'Months'.
* See also {@link rangeUnit}.
*
* @return {TemporalUnit} the period unit defining the base unit of the field.
*/
baseUnit() {
abstractMethodFail('baseUnit');
}
/**
* Gets the range that the field is bound by.
*
* The range of the field is the period that the field varies within.
* For example, in the field 'MonthOfYear', the range is 'Years'.
* See also {@link baseUnit}.
*
* The range is never null. For example, the 'Year' field is shorthand for
* 'YearOfForever'. It therefore has a unit of 'Years' and a range of 'Forever'.
*
* @return {TemporalUnit} the period unit defining the range of the field.
*/
rangeUnit() {
abstractMethodFail('rangeUnit');
}
/**
* Gets the range of valid values for the field.
*
* All fields can be expressed as an integer.
* This method returns an object that describes the valid range for that value.
* This method is generally only applicable to the ISO-8601 calendar system.
*
* Note that the result only describes the minimum and maximum valid values
* and it is important not to read too much into them. For example, there
* could be values within the range that are invalid for the field.
*
* @return {ValueRange} the range of valid values for the field.
*/
range() {
abstractMethodFail('range');
}
/**
* Get the range of valid values for this field using the temporal object to
* refine the result.
*
* This uses the temporal object to find the range of valid values for the field.
* This is similar to {@link range}, however this method refines the result
* using the temporal. For example, if the field is {@link DAY_OF_MONTH} the
* {@link range} method is not accurate as there are four possible month lengths,
* 28, 29, 30 and 31 days. Using this method with a date allows the range to be
* accurate, returning just one of those four options.
*
* There are two equivalent ways of using this method.
* The first is to invoke this method directly.
* The second is to use {@link TemporalAccessor#range}:
* <pre>
* // these two lines are equivalent, but the second approach is recommended
* temporal = thisField.rangeRefinedBy(temporal);
* temporal = temporal.range(thisField);
* </pre>
* It is recommended to use the second approach, {@link range},
* as it is a lot clearer to read in code.
*
* Implementations should perform any queries or calculations using the fields
* available in {@link ChronoField}.
* If the field is not supported a {@link DateTimeException} must be thrown.
*
* @param {!TemporalAccessor} temporal the temporal object used to refine the result.
* @return {ValueRange} the range of valid values for this field.
* @throws {DateTimeException} if the range for the field cannot be obtained.
*
*/
// eslint-disable-next-line no-unused-vars
rangeRefinedBy(temporal) {
abstractMethodFail('rangeRefinedBy');
}
/**
* Gets the value of this field from the specified temporal object.
*
* This queries the temporal object for the value of this field.
*
* There are two equivalent ways of using this method.
* The first is to invoke this method directly.
* The second is to use {@link TemporalAccessor#get}:
* <pre>
* // these two lines are equivalent, but the second approach is recommended
* temporal = thisField.getFrom(temporal);
* temporal = temporal.get(thisField);
* </pre>
* It is recommended to use the second approach, as it is a lot clearer to read in code.
*
* Implementations should perform any queries or calculations using the fields
* available in {@link ChronoField}.
* If the field is not supported a {@link DateTimeException} must be thrown.
*
* @param {!TemporalAccesor} temporal the temporal object to query.
* @return {number} the value of this field.
* @throws {DateTimeException} if a value for the field cannot be obtained.
*/
// eslint-disable-next-line no-unused-vars
getFrom(temporal) {
abstractMethodFail('getFrom');
}
/**
* Returns a copy of the specified temporal object with the value of this field set.
*
* This returns a new temporal object based on the specified one with the value for
* this field changed. For example, on a {@link LocalDate}, this could be used to
* set the year, month or day-of-month.
* The returned object has the same observable type as the specified object.
*
* In some cases, changing a field is not fully defined. For example, if the target object is
* a date representing the 31st January, then changing the month to February would be unclear.
* In cases like this, the implementation is responsible for resolving the result.
* Typically it will choose the previous valid date, which would be the last valid
* day of February in this example.
*
* There are two equivalent ways of using this method.
* The first is to invoke this method directly.
* The second is to use {@link Temporal#with}:
* <pre>
* // these two lines are equivalent, but the second approach is recommended
* temporal = thisField.adjustInto(temporal);
* temporal = temporal.with(thisField);
* </pre>
* It is recommended to use the second approach, `with(temporal)`,
* as it is a lot clearer to read in code.
*
* Implementations should perform any queries or calculations using the fields
* available in {@link ChronoField}.
* If the field is not supported a {@link DateTimeException} must be thrown.
*
* Implementations must not alter the specified temporal object.
* Instead, an adjusted copy of the original must be returned.
* This provides equivalent, safe behavior for immutable and mutable implementations.
*
* @param {!Temporal} temporal the temporal object to adjust.
* @param {!number} newValue the new value of the field.
* @return {Temporal} the adjusted temporal object.
* @throws {DateTimeException} if the field cannot be set.
*/
// eslint-disable-next-line no-unused-vars
adjustInto(temporal, newValue) {
abstractMethodFail('adjustInto');
}
/**
* Checks if this field is supported by the temporal object.
*
* This determines whether the temporal accessor supports this field.
* If this returns false, the the temporal cannot be queried for this field.
*
* There are two equivalent ways of using this method.
* The first is to invoke this method directly.
* The second is to use {@link TemporalAccessor#isSupported}:
* <pre>
* // these two lines are equivalent, but the second approach is recommended
* temporal = thisField.isSupportedBy(temporal);
* temporal = temporal.isSupported(thisField);
* </pre>
* It is recommended to use the second approach, `isSupported(temporal)`,
* as it is a lot clearer to read in code.
*
* Implementations should determine whether they are supported using the fields
* available in {@link ChronoField}.
*
* @param {!TemporalAccesor} temporal the temporal object to query.
* @return {boolean} `true` if the date-time can be queried for this field, `false` if not.
*/
// eslint-disable-next-line no-unused-vars
isSupportedBy(temporal) {
abstractMethodFail('isSupportedBy');
}
/**
* @return {string}
*/
displayName(/* TODO: locale */) {
abstractMethodFail('displayName');
}
/**
* @param {*} other
* @returns {boolean}
*/
// eslint-disable-next-line no-unused-vars
equals(other) {
abstractMethodFail('equals');
}
/**
* @returns {string}
*/
name() {
abstractMethodFail('name');
}
}

View File

@@ -0,0 +1,223 @@
/**
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
/**
* Common implementations of {@link TemporalQuery}.
*
* This class provides common implementations of {@link TemporalQuery}.
* These queries are primarily used as optimizations, allowing the internals
* of other objects to be extracted effectively. Note that application code
* can also use the {@link from} method on most temporal
* objects as a method reference matching the query interface, such as
* {@link LocalDate::from} and {@link ZoneId::from}.
*
* There are two equivalent ways of using a {@link TemporalQuery}.
* The first is to invoke the method on the interface directly.
* The second is to use {@link TemporalAccessor#query}:
* <pre>
* // these two lines are equivalent, but the second approach is recommended
* dateTime = query.queryFrom(dateTime);
* dateTime = dateTime.query(query);
* </pre>
* It is recommended to use the second approach, {@link query},
* as it is a lot clearer to read in code.
*
*/
export class TemporalQueries {
/**
* A strict query for the {@link ZoneId}.
*
* This queries a {@link TemporalAccessor} for the zone.
* The zone is only returned if the date-time conceptually contains a {@link ZoneId}.
* It will not be returned if the date-time only conceptually has an {@link ZoneOffset}.
* Thus a {@link ZonedDateTime} will return the result of
* {@link getZone}, but an {@link OffsetDateTime} will
* return null.
*
* In most cases, applications should use {@link ZONE} as this query is too strict.
*
* The result from JDK classes implementing {@link TemporalAccessor} is as follows:
* * * {@link LocalDate} returns null
* * {@link LocalTime} returns null
* * {@link LocalDateTime} returns null
* * {@link ZonedDateTime} returns the associated zone
* * {@link OffsetTime} returns null
* * {@link OffsetDateTime} returns null
* * {@link ChronoLocalDate} returns null
* * {@link ChronoLocalDateTime} returns null
* * {@link ChronoZonedDateTime} returns the associated zone
* * {@link Era} returns null
* * {@link DayOfWeek} returns null
* * {@link Month} returns null
* * {@link Year} returns null
* * {@link YearMonth} returns null
* * {@link MonthDay} returns null
* * {@link ZoneOffset} returns null
* * {@link Instant} returns null
*
* @return a query that can obtain the zone ID of a temporal, not null
*/
static zoneId() {
return TemporalQueries.ZONE_ID;
}
/**
* A query for the {@link Chronology}.
*
* This queries a {@link TemporalAccessor} for the chronology.
* If the target {@link TemporalAccessor} represents a date, or part of a date,
* then it should return the chronology that the date is expressed in.
* As a result of this definition, objects only representing time, such as
* {@link LocalTime}, will return null.
*
* The result from js-joda classes implementing {@link TemporalAccessor} is as follows:
*
* * {@link LocalDate} returns * {@link IsoChronology.INSTANCE}
* * {@link LocalTime} returns null (does not represent a date)
* * {@link LocalDateTime} returns * {@link IsoChronology.INSTANCE}
* * {@link ZonedDateTime} returns * {@link IsoChronology.INSTANCE}
* * {@link OffsetTime} returns null (does not represent a date)
* * {@link OffsetDateTime} returns * {@link IsoChronology.INSTANCE}
* * {@link ChronoLocalDate} returns the associated chronology
* * {@link ChronoLocalDateTime} returns the associated chronology
* * {@link ChronoZonedDateTime} returns the associated chronology
* * {@link Era} returns the associated chronology
* * {@link DayOfWeek} returns null (shared across chronologies)
* * {@link Month} returns * {@link IsoChronology.INSTANCE}
* * {@link Year} returns * {@link IsoChronology.INSTANCE}
* * {@link YearMonth} returns * {@link IsoChronology.INSTANCE}
* * {@link MonthDay} returns null * {@link IsoChronology.INSTANCE}
* * {@link ZoneOffset} returns null (does not represent a date)
* * {@link Instant} returns null (does not represent a date)
*
* The method {@link Chronology#from} can be used as a
* {@link TemporalQuery}
* That method is equivalent to this query, except that it throws an
* exception if a chronology cannot be obtained.
*
* @return {TemporalQuery} a query that can obtain the chronology of a temporal, not null
*/
static chronology() {
return TemporalQueries.CHRONO;
}
/**
* A query for the smallest supported unit.
*
* This queries a {@link TemporalAccessor} for the time precision.
* If the target {@link TemporalAccessor} represents a consistent or complete date-time,
* date or time then this must return the smallest precision actually supported.
* Note that fields such as {@link NANO_OF_DAY} and {@link NANO_OF_SECOND}
* are defined to always return ignoring the precision, thus this is the only
* way to find the actual smallest supported unit.
* For example, were {@link GregorianCalendar} to implement {@link TemporalAccessor}
* it would return a precision of {@link MILLIS}.
*
* The result from js-joda classes implementing {@link TemporalAccessor} is as follows:
*
* {@link LocalDate} returns {@link DAYS}
* {@link LocalTime} returns {@link NANOS}
* {@link LocalDateTime} returns {@link NANOS}
* {@link ZonedDateTime} returns {@link NANOS}
* {@link OffsetTime} returns {@link NANOS}
* {@link OffsetDateTime} returns {@link NANOS}
* {@link ChronoLocalDate} returns {@link DAYS}
* {@link ChronoLocalDateTime} returns {@link NANOS}
* {@link ChronoZonedDateTime} returns {@link NANOS}
* {@link Era} returns {@link ERAS}
* {@link DayOfWeek} returns {@link DAYS}
* {@link Month} returns {@link MONTHS}
* {@link Year} returns {@link YEARS}
* {@link YearMonth} returns {@link MONTHS}
* {@link MonthDay} returns null (does not represent a complete date or time)
* {@link ZoneOffset} returns null (does not represent a date or time)
* {@link Instant} returns {@link NANOS}
*
* @return a query that can obtain the precision of a temporal, not null
*/
static precision() {
return TemporalQueries.PRECISION;
}
/**
* A lenient query for the {@link ZoneId}, falling back to the {@link ZoneOffset}.
*
* This queries a {@link TemporalAccessor} for the zone.
* It first tries to obtain the zone, using {@link zoneId}.
* If that is not found it tries to obtain the {@link offset}.
*
* In most cases, applications should use this query rather than {@link zoneId}.
*
* This query examines the {@link ChronoField#OFFSET_SECONDS}
* field and uses it to create a {@link ZoneOffset}.
*
* The method {@link ZoneId#from} can be used as a
* {@link TemporalQuery} via a method reference, {@link ZoneId::from}.
* That method is equivalent to this query, except that it throws an
* exception if a zone cannot be obtained.
*
* @return a query that can obtain the zone ID or offset of a temporal, not null
*/
static zone() {
return TemporalQueries.ZONE;
}
/**
* A query for {@link ZoneOffset} returning null if not found.
*
* This returns a {@link TemporalQuery} that can be used to query a temporal
* object for the offset. The query will return null if the temporal
* object cannot supply an offset.
*
* The query implementation examines the {@link ChronoField#OFFSET_SECONDS}
* field and uses it to create a {@link ZoneOffset}.
*
* The method {@link java.time.ZoneOffset#from} can be used as a
* {@link TemporalQuery} via a method reference, {@link ZoneOffset::from}.
* This query and {@link ZoneOffset::from} will return the same result if the
* temporal object contains an offset. If the temporal object does not contain
* an offset, then the method reference will throw an exception, whereas this
* query will return null.
*
* @return a query that can obtain the offset of a temporal, not null
*/
static offset() {
return TemporalQueries.OFFSET;
}
/**
* A query for {@link LocalDate} returning null if not found.
*
* This returns a {@link TemporalQuery} that can be used to query a temporal
* object for the local date. The query will return null if the temporal
* object cannot supply a local date.
*
* The query implementation examines the {@link ChronoField#EPOCH_DAY}
* field and uses it to create a {@link LocalDate}.
*
* @return a query that can obtain the date of a temporal, not null
*/
static localDate() {
return TemporalQueries.LOCAL_DATE;
}
/**
* A query for {@link LocalTime} returning null if not found.
*
* This returns a {@link TemporalQuery} that can be used to query a temporal
* object for the local time. The query will return null if the temporal
* object cannot supply a local time.
*
* The query implementation examines the {@link ChronoField#NANO_OF_DAY}
* field and uses it to create a {@link LocalTime}.
*
* @return a query that can obtain the time of a temporal, not null
*/
static localTime() {
return TemporalQueries.LOCAL_TIME;
}
}

View File

@@ -0,0 +1,77 @@
/*
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
import { ChronoField } from './ChronoField';
import { createTemporalQuery } from './TemporalQuery';
import { TemporalQueries } from './TemporalQueries';
import { LocalDate } from '../LocalDate';
import { LocalTime } from '../LocalTime';
import { ZoneOffset } from '../ZoneOffset';
export function _init() {
//-----------------------------------------------------------------------
/**
* A strict query for the {@link ZoneId}.
*/
TemporalQueries.ZONE_ID = createTemporalQuery('ZONE_ID', (temporal) => {
return temporal.query(TemporalQueries.ZONE_ID);
});
/**
* A query for the {@link Chronology}.
*/
TemporalQueries.CHRONO = createTemporalQuery('CHRONO', (temporal) => {
return temporal.query(TemporalQueries.CHRONO);
});
/**
* A query for the smallest supported unit.
*/
TemporalQueries.PRECISION = createTemporalQuery('PRECISION', (temporal) => {
return temporal.query(TemporalQueries.PRECISION);
});
//-----------------------------------------------------------------------
/**
* A query for {@link ZoneOffset} returning null if not found.
*/
TemporalQueries.OFFSET = createTemporalQuery('OFFSET', (temporal) => {
if (temporal.isSupported(ChronoField.OFFSET_SECONDS)) {
return ZoneOffset.ofTotalSeconds(temporal.get(ChronoField.OFFSET_SECONDS));
}
return null;
});
/**
* A lenient query for the {@link ZoneId}, falling back to the {@link ZoneOffset}.
*/
TemporalQueries.ZONE = createTemporalQuery('ZONE', (temporal) => {
const zone = temporal.query(TemporalQueries.ZONE_ID);
return (zone != null ? zone : temporal.query(TemporalQueries.OFFSET));
});
/**
* A query for {@link LocalDate} returning null if not found.
*/
TemporalQueries.LOCAL_DATE = createTemporalQuery('LOCAL_DATE', (temporal) => {
if (temporal.isSupported(ChronoField.EPOCH_DAY)) {
return LocalDate.ofEpochDay(temporal.getLong(ChronoField.EPOCH_DAY));
}
return null;
});
/**
* A query for {@link LocalTime} returning null if not found.
*/
TemporalQueries.LOCAL_TIME = createTemporalQuery('LOCAL_TIME', (temporal) => {
if (temporal.isSupported(ChronoField.NANO_OF_DAY)) {
return LocalTime.ofNanoOfDay(temporal.getLong(ChronoField.NANO_OF_DAY));
}
return null;
});
}

View File

@@ -0,0 +1,109 @@
/*
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
import { abstractMethodFail } from '../assert';
import { Enum } from '../Enum';
/**
* Strategy for querying a temporal object.
*
* Queries are a key tool for extracting information from temporal objects.
* They exist to externalize the process of querying, permitting different
* approaches, as per the strategy design pattern.
* Examples might be a query that checks if the date is the day before February 29th
* in a leap year, or calculates the number of days to your next birthday.
*
* The {@link TemporalField} interface provides another mechanism for querying
* temporal objects. That interface is limited to returning a `long`.
* By contrast, queries can return any type.
*
* There are two equivalent ways of using a {@link TemporalQuery}.
* The first is to invoke the method on this interface directly.
* The second is to use {@link TemporalAccessor#query}:
* <pre>
* // these two lines are equivalent, but the second approach is recommended
* temporal = thisQuery.queryFrom(temporal);
* temporal = temporal.query(thisQuery);
* </pre>
* It is recommended to use the second approach, {@link query},
* as it is a lot clearer to read in code.
*
* The most common implementations are method references, such as
* {@link LocalDate::from} and {@link ZoneId::from}.
* Further implementations are on {@link TemporalQueries}.
* Queries may also be defined by applications.
*
* ### Specification for implementors
*
* This interface places no restrictions on the mutability of implementations,
* however immutability is strongly recommended.
*
* @interface
*/
export class TemporalQuery extends Enum {
/**
* Queries the specified temporal object.
*
* This queries the specified temporal object to return an object using the logic
* encapsulated in the implementing class.
* Examples might be a query that checks if the date is the day before February 29th
* in a leap year, or calculates the number of days to your next birthday.
*
* There are two equivalent ways of using this method.
* The first is to invoke this method directly.
* The second is to use {@link TemporalAccessor#query}:
* <pre>
* // these two lines are equivalent, but the second approach is recommended
* temporal = thisQuery.queryFrom(temporal);
* temporal = temporal.query(thisQuery);
* </pre>
* It is recommended to use the second approach, {@link query},
* as it is a lot clearer to read in code.
*
* ### Specification for implementors
*
* The implementation must take the input object and query it.
* The implementation defines the logic of the query and is responsible for
* documenting that logic.
* It may use any method on {@link TemporalAccessor} to determine the result.
* The input object must not be altered.
*
* The input temporal object may be in a calendar system other than ISO.
* Implementations may choose to document compatibility with other calendar systems,
* or reject non-ISO temporal objects by querying the chronology (see {@link TemporalQueries#chronology}).
*
* This method may be called from multiple threads in parallel.
* It must be thread-safe when invoked.
*
* @param {TemporalAccessor} temporal the temporal object to query, not null
* @return the queried value, may return null to indicate not found
* @throws DateTimeException if unable to query
* @throws ArithmeticException if numeric overflow occurs
*/
// eslint-disable-next-line no-unused-vars
queryFrom(temporal){
abstractMethodFail('queryFrom');
}
}
/**
* @private
*
* Factory to create something similar to the JSR-310 {TemporalQuery} interface, takes a function and returns a new TemporalQuery object that presents that function
* as the queryFrom() function.
* @param name for the underlying Enum
* @param queryFromFunction
*/
export function createTemporalQuery(name, queryFromFunction) {
class ExtendedTemporalQuery extends TemporalQuery {
}
ExtendedTemporalQuery.prototype.queryFrom = queryFromFunction;
return new ExtendedTemporalQuery(name);
}

179
node_modules/@js-joda/core/src/temporal/TemporalUnit.js generated vendored Normal file
View File

@@ -0,0 +1,179 @@
/*
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
import { abstractMethodFail } from '../assert';
/**
* A unit of date-time, such as Days or Hours.
*
* Measurement of time is built on units, such as years, months, days, hours, minutes and seconds.
* Implementations of this interface represent those units.
*
* An instance of this interface represents the unit itself, rather than an amount of the unit.
* See {@link Period} for a class that represents an amount in terms of the common units.
*
* The most commonly used units are defined in {@link ChronoUnit}.
* Further units are supplied in {@link IsoFields}.
* Units can also be written by application code by implementing this interface.
*
* The unit works using double dispatch. Client code calls methods on a date-time like
* {@link LocalDateTime} which check if the unit is a {@link ChronoUnit}.
* If it is, then the date-time must handle it.
* Otherwise, the method call is re-dispatched to the matching method in this interface.
*
* @interface
*/
export class TemporalUnit {
/**
* Gets the duration of this unit, which may be an estimate.
*
* All units return a duration measured in standard nanoseconds from this method.
* The duration will be positive and non-zero.
* For example, an hour has a duration of `60 * 60 * 1,000,000,000 ns`.
*
* Some units may return an accurate duration while others return an estimate.
* For example, days have an estimated duration due to the possibility of
* daylight saving time changes.
* To determine if the duration is an estimate, use {@link isDurationEstimated}.
*
* @return {Duration} the duration of this unit, which may be an estimate.
*/
duration() {
abstractMethodFail('duration');
}
/**
* Checks if the duration of the unit is an estimate.
*
* All units have a duration, however the duration is not always accurate.
* For example, days have an estimated duration due to the possibility of
* daylight saving time changes.
* This method returns true if the duration is an estimate and false if it is
* accurate. Note that accurate/estimated ignores leap seconds.
*
* @return {boolean} `true` if the duration is estimated, `false` if accurate.
*/
isDurationEstimated() {
abstractMethodFail('isDurationEstimated');
}
/**
* Checks if this unit is date-based.
*
* @return {boolean} `true` if date unit, `false` if a time unit.
*/
isDateBased() {
abstractMethodFail('isDateBased');
}
/**
* Checks if this unit is time-based.
*
* @return {boolean} `true` if time unit, `false` if a date unit.
*/
isTimeBased() {
abstractMethodFail('isTimeBased');
}
//-----------------------------------------------------------------------
/**
* Checks if this unit is supported by the specified temporal object.
*
* This checks that the implementing date-time can add/subtract this unit.
* This can be used to avoid throwing an exception.
*
* @param {!Temporal} temporal the temporal object to check.
* @return {boolean} `true` if the unit is supported.
*/
// eslint-disable-next-line no-unused-vars
isSupportedBy(temporal) {
abstractMethodFail('isSupportedBy');
}
/**
* Returns a copy of the specified temporal object with the specified period added.
*
* The period added is a multiple of this unit. For example, this method
* could be used to add "3 days" to a date by calling this method on the
* instance representing "days", passing the date and the period "3".
* The period to be added may be negative, which is equivalent to subtraction.
*
* There are two equivalent ways of using this method.
* The first is to invoke this method directly.
* The second is to use {@link Temporal#plus}:
* <pre>
* // these two lines are equivalent, but the second approach is recommended
* temporal = thisUnit.doPlus(temporal);
* temporal = temporal.plus(thisUnit);
* </pre>
* It is recommended to use the second approach, {@link plus},
* as it is a lot clearer to read in code.
*
* Implementations should perform any queries or calculations using the units
* available in {@link ChronoUnit} or the fields available in {@link ChronoField}.
* If the field is not supported a {@link DateTimeException} must be thrown.
*
* Implementations must not alter the specified temporal object.
* Instead, an adjusted copy of the original must be returned.
* This provides equivalent, safe behavior for immutable and mutable implementations.
*
* @param {!Temporal} dateTime the temporal object to adjust.
* @param {number} periodToAdd the period of this unit to add, positive or negative.
* @return {Temporal} the adjusted temporal object.
* @throws DateTimeException if the period cannot be added.
*/
// eslint-disable-next-line no-unused-vars
addTo(dateTime, periodToAdd) {
abstractMethodFail('addTo');
}
//-----------------------------------------------------------------------
/**
* Calculates the period in terms of this unit between two temporal objects of the same type.
*
* This calculates the period between two temporals in terms of this unit.
* The start and end points are supplied as temporal objects and must be of the same type.
* The result will be negative if the end is before the start.
* For example, the period in hours between two temporal objects can be calculated
* using {@link HOURS.between}.
*
* The calculation returns a whole number, representing the number of complete units between the two temporals.
* For example, the period in hours between the times 11:30 and 13:29 will only be
* one hour as it is one minute short of two hours.
*
* There are two equivalent ways of using this method.
* The first is to invoke this method directly.
* The second is to use {@link Temporal#until}:
* <pre>
* // these two lines are equivalent
* between = thisUnit.between(start, end);
* between = start.until(end, thisUnit);
* </pre>
* The choice should be made based on which makes the code more readable.
*
* For example, this method allows the number of days between two dates to be calculated:
* <pre>
* long daysBetween = DAYS.between(start, end);
* // or alternatively
* long daysBetween = start.until(end, DAYS);
* </pre>
* Implementations should perform any queries or calculations using the units available in
* {@link ChronoUnit} or the fields available in {@link ChronoField}.
* If the unit is not supported a {@link DateTimeException} must be thrown.
* Implementations must not alter the specified temporal objects.
*
* @param {!Temporal} temporal1 the base temporal object.
* @param {!Temporal} temporal2 the other temporal object.
* @return {number} the period between temporal1 and temporal2 in terms of this unit;
* positive if temporal2 is later than temporal1, negative if earlier.
* @throws DateTimeException if the period cannot be calculated.
* @throws ArithmeticException if numeric overflow occurs.
*/
// eslint-disable-next-line no-unused-vars
between(temporal1, temporal2) {
abstractMethodFail('between');
}
}

257
node_modules/@js-joda/core/src/temporal/ValueRange.js generated vendored Normal file
View File

@@ -0,0 +1,257 @@
/**
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
import { assert } from '../assert';
import { DateTimeException, IllegalArgumentException } from '../errors';
import { MathUtil } from '../MathUtil';
/**
* The range of valid values for a date-time field.
*
* All TemporalField instances have a valid range of values.
* For example, the ISO day-of-month runs from 1 to somewhere between 28 and 31.
* This class captures that valid range.
*
* It is important to be aware of the limitations of this class.
* Only the minimum and maximum values are provided.
* It is possible for there to be invalid values within the outer range.
* For example, a weird field may have valid values of 1, 2, 4, 6, 7, thus
* have a range of '1 - 7', despite that fact that values 3 and 5 are invalid.
*
* Instances of this class are not tied to a specific field.
*/
export class ValueRange {
/**
*
* @param {!number} minSmallest
* @param {!number} minLargest
* @param {!number} maxSmallest
* @param {!number} maxLargest
* @private
*/
constructor(minSmallest, minLargest, maxSmallest, maxLargest) {
assert(!(minSmallest > minLargest), `Smallest minimum value '${minSmallest
}' must be less than largest minimum value '${minLargest}'`, IllegalArgumentException);
assert(!(maxSmallest > maxLargest), `Smallest maximum value '${maxSmallest
}' must be less than largest maximum value '${maxLargest}'`, IllegalArgumentException);
assert(!(minLargest > maxLargest), `Minimum value '${minLargest
}' must be less than maximum value '${maxLargest}'`, IllegalArgumentException);
this._minSmallest = minSmallest;
this._minLargest = minLargest;
this._maxLargest = maxLargest;
this._maxSmallest = maxSmallest;
}
/**
* Is the value range fixed and fully known.
*
* For example, the ISO day-of-month runs from 1 to between 28 and 31.
* Since there is uncertainty about the maximum value, the range is not fixed.
* However, for the month of January, the range is always 1 to 31, thus it is fixed.
*
* @return {boolean} true if the set of values is fixed
*/
isFixed() {
return this._minSmallest === this._minLargest && this._maxSmallest === this._maxLargest;
}
/**
*
* @returns {number}
*/
minimum(){
return this._minSmallest;
}
/**
*
* @returns {number}
*/
largestMinimum(){
return this._minLargest;
}
/**
*
* @returns {number}
*/
maximum(){
return this._maxLargest;
}
/**
*
* @returns {number}
*/
smallestMaximum(){
return this._maxSmallest;
}
/**
*
* @returns {boolean}
*/
isValidValue(value) {
return (this.minimum() <= value && value <= this.maximum());
}
/**
*
* @param {number} value
* @param {TemporalField} field
*/
checkValidValue(value, field) {
let msg;
if (!this.isValidValue(value)) {
if (field != null) {
msg = `Invalid value for ${field} (valid values ${this.toString()}): ${value}`;
} else {
msg = `Invalid value (valid values ${this.toString()}): ${value}`;
}
return assert(false, msg, DateTimeException);
}
return value;
}
/**
* Checks that the specified value is valid and fits in an `int`.
*
* This validates that the value is within the valid range of values and that
* all valid values are within the bounds of an `int`.
* The field is only used to improve the error message.
*
* @param {number} value - the value to check
* @param {TemporalField} field - the field being checked, may be null
* @return {number} the value that was passed in
* @see #isValidIntValue(long)
*/
checkValidIntValue(value, field) {
if (this.isValidIntValue(value) === false) {
throw new DateTimeException(`Invalid int value for ${field}: ${value}`);
}
return value;
}
/**
* Checks if the value is within the valid range and that all values
* in the range fit in an `int`.
*
* This method combines {@link isIntValue} and {@link isValidValue}.
*
* @param {number} value - the value to check
* @return true if the value is valid and fits in an `int`
*/
isValidIntValue(value) {
return this.isIntValue() && this.isValidValue(value);
}
/**
* Checks if all values in the range fit in an `int`.
*
* This checks that all valid values are within the bounds of an `int`.
*
* For example, the ISO month-of-year has values from 1 to 12, which fits in an `int`.
* By comparison, ISO nano-of-day runs from 1 to 86,400,000,000,000 which does not fit in an `int`.
*
* This implementation uses {@link getMinimum} and {@link getMaximum}.
*
* @return boolean if a valid value always fits in an `int`
*/
isIntValue() { // should be isSafeIntegerValue
return this.minimum() >= MathUtil.MIN_SAFE_INTEGER && this.maximum() <= MathUtil.MAX_SAFE_INTEGER;
}
/**
* Checks if this range is equal to another range.
*
* The comparison is based on the four values, minimum, largest minimum,
* smallest maximum and maximum.
* Only objects of type {@link ValueRange} are compared, other types return false.
*
* @param {*} other - the object to check, null returns false
* @return {boolean} true if this is equal to the other range
*/
equals(other) {
if (other === this) {
return true;
}
if (other instanceof ValueRange) {
return this._minSmallest === other._minSmallest && this._minLargest === other._minLargest &&
this._maxSmallest === other._maxSmallest && this._maxLargest === other._maxLargest;
}
return false;
}
/**
* A hash code for this range.
*
* @return {number} a suitable hash code
*/
hashCode() {
return MathUtil.hashCode(this._minSmallest, this._minLargest, this._maxSmallest, this._maxLargest);
}
/*
* Outputs this range as a String.
*
* The format will be '{min}/{largestMin} - {smallestMax}/{max}',
* where the largestMin or smallestMax sections may be omitted, together
* with associated slash, if they are the same as the min or max.
*
* @return {string} a string representation of this range, not null
*/
toString() {
let str = this.minimum() + (this.minimum() !== this.largestMinimum() ? `/${this.largestMinimum()}` : '');
str += ' - ';
str += this.smallestMaximum() + (this.smallestMaximum() !== this.maximum() ? `/${this.maximum()}` : '');
return str;
}
/*
* called with 2 params: Obtains a fixed value range.
*
* This factory obtains a range where the minimum and maximum values are fixed.
* For example, the ISO month-of-year always runs from 1 to 12.
*
* @param min the minimum value
* @param max the maximum value
* @return the ValueRange for min, max, not null
* called with 3 params: Obtains a variable value range.
*
* This factory obtains a range where the minimum value is fixed and the maximum value may vary.
* For example, the ISO day-of-month always starts at 1, but ends between 28 and 31.
*
* @param min the minimum value
* @param maxSmallest the smallest maximum value
* @param maxLargest the largest maximum value
* @return the ValueRange for min, smallest max, largest max, not null
* called with 4 params: Obtains a fully variable value range.
*
* This factory obtains a range where both the minimum and maximum value may vary.
*
* @param minSmallest the smallest minimum value
* @param minLargest the largest minimum value
* @param maxSmallest the smallest maximum value
* @param maxLargest the largest maximum value
*
* @return {ValueRange} the ValueRange for smallest min, largest min, smallest max, largest max, not null
*/
static of() {
if (arguments.length === 2) {
return new ValueRange(arguments[0], arguments[0], arguments[1], arguments[1]);
} else if (arguments.length === 3) {
return new ValueRange(arguments[0], arguments[0], arguments[1], arguments[2]);
} else if (arguments.length === 4) {
return new ValueRange(arguments[0], arguments[1], arguments[2], arguments[3]);
} else {
return assert(false, `Invalid number of arguments ${arguments.length}`, IllegalArgumentException);
}
}
}

25
node_modules/@js-joda/core/src/use.js generated vendored Normal file
View File

@@ -0,0 +1,25 @@
/**
* @private
*
* @param jsJoda
* @returns { function(jsJoda: JsJoda) }
*/
export function bindUse(jsJoda) {
const used = [];
/**
* use
*
* Provides a way to extend the internals of js-joda
*
* @param {function} fn - function to extend js-joda public api
* @returns {this} for chaining
*/
return function use(fn) {
if (!~used.indexOf(fn)) {
fn(jsJoda);
used.push(fn);
}
return jsJoda;
};
}

View File

@@ -0,0 +1,31 @@
/*
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
import { SystemDefaultZoneRules } from './SystemDefaultZoneRules';
import { ZoneId } from '../ZoneId';
export class SystemDefaultZoneId extends ZoneId {
constructor(){
super();
this._rules = new SystemDefaultZoneRules();
}
rules(){
return this._rules;
}
equals(other){
if(this === other){
return true;
}
return false;
}
id(){
return 'SYSTEM';
}
}

View File

@@ -0,0 +1,162 @@
/*
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
import { ZoneRules } from './ZoneRules';
import { ZoneOffset } from '../ZoneOffset';
import { DateTimeException } from '../errors';
export class SystemDefaultZoneRules extends ZoneRules {
isFixedOffset(){
return false;
}
/**
*
* @param {Instant} instant
* @returns {ZoneOffset}
*/
offsetOfInstant(instant){
const offsetInMinutes = new Date(instant.toEpochMilli()).getTimezoneOffset();
return ZoneOffset.ofTotalMinutes(offsetInMinutes * -1);
}
/**
*
* @param {number} epochMilli
* @returns {ZoneOffset}
*/
offsetOfEpochMilli(epochMilli){
const offsetInMinutes = new Date(epochMilli).getTimezoneOffset();
return ZoneOffset.ofTotalMinutes(offsetInMinutes * -1);
}
/**
* This implementation is NOT returning the best value in a gap or overlap situation
* as specified at {@link ZoneRules.offsetOfLocalDateTime}.
*
* The calculated offset depends Date.prototype.getTimezoneOffset and its not specified
* at the ECMA-262 specification how to handle daylight savings gaps/ overlaps.
*
* The Chrome Browser version 49 is returning the next transition offset in a gap/overlap situation,
* other browsers/ engines might do it in the same way.
*
* @param {LocalDateTime} localDateTime
* @returns {ZoneOffset}
*/
offsetOfLocalDateTime(localDateTime){
const epochMilli = localDateTime.toEpochSecond(ZoneOffset.UTC) * 1000;
const offsetInMinutesBeforePossibleTransition = new Date(epochMilli).getTimezoneOffset();
const epochMilliSystemZone = epochMilli + offsetInMinutesBeforePossibleTransition * 60000;
const offsetInMinutesAfterPossibleTransition = new Date(epochMilliSystemZone).getTimezoneOffset();
return ZoneOffset.ofTotalMinutes(offsetInMinutesAfterPossibleTransition * -1);
}
/**
*
* @param localDateTime
* @return {ZoneOffset[]}
*/
validOffsets(localDateTime){
return [this.offsetOfLocalDateTime(localDateTime)];
}
/**
* @return null, not supported
*/
transition(){
return null;
}
/**
*
* @param instant
* @return {ZoneOffset}
*/
standardOffset(instant){
return this.offsetOfInstant(instant);
}
/**
* @throws DateTimeException not supported
*/
daylightSavings(){
this._throwNotSupported();
}
/**
* @throws DateTimeException not supported
*/
isDaylightSavings(){
this._throwNotSupported();
}
/**
*
* @param {LocalDateTime} dateTime
* @param {ZoneOffset} offset
* @return {boolean}
*/
isValidOffset(dateTime, offset) {
return this.offsetOfLocalDateTime(dateTime).equals(offset);
}
/**
* @throws DateTimeException not supported
*/
nextTransition(){
this._throwNotSupported();
}
/**
* @throws DateTimeException not supported
*/
previousTransition(){
this._throwNotSupported();
}
/**
* @throws DateTimeException not supported
*/
transitions(){
this._throwNotSupported();
}
/**
* @throws DateTimeException not supported
*/
transitionRules(){
this._throwNotSupported();
}
/**
* @throws DateTimeException not supported
*/
_throwNotSupported(){
throw new DateTimeException('not supported operation');
}
//-----------------------------------------------------------------------
/**
*
* @param {*} other
* @returns {boolean}
*/
equals(other) {
if (this === other || other instanceof SystemDefaultZoneRules) {
return true;
} else {
return false;
}
}
/**
*
* @returns {string}
*/
toString() {
return 'SYSTEM';
}
}

View File

@@ -0,0 +1,289 @@
/*
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
import { requireNonNull } from '../assert';
import { IllegalArgumentException } from '../errors';
import { Duration } from '../Duration';
import { LocalDateTime } from '../LocalDateTime';
/**
* A transition between two offsets caused by a discontinuity in the local time-line.
*
* A transition between two offsets is normally the result of a daylight savings cutover.
* The discontinuity is normally a gap in spring and an overlap in autumn.
* {@link ZoneOffsetTransition} models the transition between the two offsets.
*
* Gaps occur where there are local date-times that simply do not not exist.
* An example would be when the offset changes from `+03:00` to `+04:00`.
* This might be described as 'the clocks will move forward one hour tonight at 1am'.
*
* Overlaps occur where there are local date-times that exist twice.
* An example would be when the offset changes from `+04:00` to `+03:00`.
* This might be described as 'the clocks will move back one hour tonight at 2am'.
*
*/
export class ZoneOffsetTransition {
//-----------------------------------------------------------------------
/**
* Obtains an instance defining a transition between two offsets.
*
* Applications should normally obtain an instance from {@link ZoneRules}.
* This factory is only intended for use when creating {@link ZoneRules}.
*
* @param {LocalDateTime} transition - the transition date-time at the transition, which never
* actually occurs, expressed local to the before offset, not null
* @param {ZoneOffset} offsetBefore - the offset before the transition, not null
* @param {ZoneOffset} offsetAfter - the offset at and after the transition, not null
* @return {ZoneOffsetTransition} the transition, not null
* @throws IllegalArgumentException if {@link offsetBefore} and {@link offsetAfter}
* are equal, or {@link transition.getNano} returns non-zero value
*/
static of(transition, offsetBefore, offsetAfter) {
return new ZoneOffsetTransition(transition, offsetBefore, offsetAfter);
}
/**
* Creates an instance defining a transition between two offsets.
* Creates an instance from epoch-second if transition is not a LocalDateTimeInstance
*
* @param {(LocalDateTime \ number)} transition - the transition date-time with the offset before the transition, not null
* @param {ZoneOffset} offsetBefore - the offset before the transition, not null
* @param {ZoneOffset} offsetAfter - the offset at and after the transition, not null
* @private
*/
constructor(transition, offsetBefore, offsetAfter) {
requireNonNull(transition, 'transition');
requireNonNull(offsetBefore, 'offsetBefore');
requireNonNull(offsetAfter, 'offsetAfter');
if (offsetBefore.equals(offsetAfter)) {
throw new IllegalArgumentException('Offsets must not be equal');
}
if (transition.nano() !== 0) {
throw new IllegalArgumentException('Nano-of-second must be zero');
}
if(transition instanceof LocalDateTime) {
this._transition = transition;
} else {
this._transition = LocalDateTime.ofEpochSecond(transition, 0, offsetBefore);
}
this._offsetBefore = offsetBefore;
this._offsetAfter = offsetAfter;
}
//-----------------------------------------------------------------------
/**
* Gets the transition instant.
*
* This is the instant of the discontinuity, which is defined as the first
* instant that the 'after' offset applies.
*
* The methods {@link getInstant}, {@link getDateTimeBefore} and {@link getDateTimeAfter}
* all represent the same instant.
*
* @return {Instant} the transition instant, not null
*/
instant() {
return this._transition.toInstant(this._offsetBefore);
}
/**
* Gets the transition instant as an epoch second.
*
* @return {number} the transition epoch second
*/
toEpochSecond() {
return this._transition.toEpochSecond(this._offsetBefore);
}
//-------------------------------------------------------------------------
/**
* Gets the local transition date-time, as would be expressed with the 'before' offset.
*
* This is the date-time where the discontinuity begins expressed with the 'before' offset.
* At this instant, the 'after' offset is actually used, therefore the combination of this
* date-time and the 'before' offset will never occur.
*
* The combination of the 'before' date-time and offset represents the same instant
* as the 'after' date-time and offset.
*
* @return {LocalDateTime} the transition date-time expressed with the before offset, not null
*/
dateTimeBefore(){
return this._transition;
}
/**
* Gets the local transition date-time, as would be expressed with the 'after' offset.
*
* This is the first date-time after the discontinuity, when the new offset applies.
*
* The combination of the 'before' date-time and offset represents the same instant
* as the 'after' date-time and offset.
*
* @return {LocalDateTime} the transition date-time expressed with the after offset, not null
*/
dateTimeAfter() {
return this._transition.plusSeconds(this.durationSeconds());
}
/**
* Gets the offset before the transition.
*
* This is the offset in use before the instant of the transition.
*
* @return {ZoneOffset} the offset before the transition, not null
*/
offsetBefore() {
return this._offsetBefore;
}
/**
* Gets the offset after the transition.
*
* This is the offset in use on and after the instant of the transition.
*
* @return {ZoneOffset} the offset after the transition, not null
*/
offsetAfter() {
return this._offsetAfter;
}
/**
* Gets the duration of the transition.
*
* In most cases, the transition duration is one hour, however this is not always the case.
* The duration will be positive for a gap and negative for an overlap.
* Time-zones are second-based, so the nanosecond part of the duration will be zero.
*
* @return {Duration} the duration of the transition, positive for gaps, negative for overlaps
*/
duration() {
return Duration.ofSeconds(this.durationSeconds());
}
/**
* Gets the duration of the transition in seconds.
*
* @return {number} the duration in seconds
*/
durationSeconds() {
return this._offsetAfter.totalSeconds() - this._offsetBefore.totalSeconds();
}
/**
* Does this transition represent a gap in the local time-line.
*
* Gaps occur where there are local date-times that simply do not not exist.
* An example would be when the offset changes from `+01:00` to `+02:00`.
* This might be described as 'the clocks will move forward one hour tonight at 1am'.
*
* @return {boolean} true if this transition is a gap, false if it is an overlap
*/
isGap() {
return this._offsetAfter.totalSeconds() > this._offsetBefore.totalSeconds();
}
/**
* Does this transition represent a gap in the local time-line.
*
* Overlaps occur where there are local date-times that exist twice.
* An example would be when the offset changes from `+02:00` to `+01:00`.
* This might be described as 'the clocks will move back one hour tonight at 2am'.
*
* @return {boolean} true if this transition is an overlap, false if it is a gap
*/
isOverlap() {
return this._offsetAfter.totalSeconds() < this._offsetBefore.totalSeconds();
}
/**
* Checks if the specified offset is valid during this transition.
*
* This checks to see if the given offset will be valid at some point in the transition.
* A gap will always return false.
* An overlap will return true if the offset is either the before or after offset.
*
* @param {ZoneOffset} offset - the offset to check, null returns false
* @return {boolean} true if the offset is valid during the transition
*/
isValidOffset(offset) {
return this.isGap() ? false : (this._offsetBefore.equals(offset) || this._offsetAfter.equals(offset));
}
/**
* Gets the valid offsets during this transition.
*
* A gap will return an empty list, while an overlap will return both offsets.
*
* @return {ZoneOffset[]} the list of valid offsets
*/
validOffsets() {
if (this.isGap()){
return [];
} else {
return [this._offsetBefore, this._offsetAfter];
}
}
//-----------------------------------------------------------------------
/**
* Compares this transition to another based on the transition instant.
*
* This compares the instants of each transition.
* The offsets are ignored, making this order inconsistent with equals.
*
* @param {ZoneOffsetTransition} transition - the transition to compare to, not null
* @return {number} the comparator value, negative if less, positive if greater
*/
compareTo(transition) {
return this.instant().compareTo(transition.instant());
}
//-----------------------------------------------------------------------
/**
* Checks if this object equals another.
*
* The entire state of the object is compared.
*
* @param {*} other - the other object to compare to, null returns false
* @return true if equal
*/
equals(other) {
if (other === this) {
return true;
}
if (other instanceof ZoneOffsetTransition) {
const d = other;
return this._transition.equals(d._transition) &&
this._offsetBefore.equals(d.offsetBefore()) && this._offsetAfter.equals(d.offsetAfter());
}
return false;
}
/**
* Returns a suitable hash code.
*
* @return {number} the hash code
*/
hashCode() {
return this._transition.hashCode() ^ this._offsetBefore.hashCode() ^ (this._offsetAfter.hashCode()>>>16);
}
//-----------------------------------------------------------------------
/**
* Returns a string describing this object.
*
* @return {string} a string for debugging, not null
*/
toString() {
return `Transition[${this.isGap() ? 'Gap' : 'Overlap'
} at ${this._transition.toString()}${this._offsetBefore.toString()
} to ${this._offsetAfter}]`;
}
}

464
node_modules/@js-joda/core/src/zone/ZoneRules.js generated vendored Normal file
View File

@@ -0,0 +1,464 @@
/*
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
* @copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
import { requireNonNull, abstractMethodFail } from '../assert';
import { Duration } from '../Duration';
import { Instant } from '../Instant';
export class ZoneRules {
/**
* Obtains an instance of {@link ZoneRules} that always uses the same offset.
*
* The returned rules always have the same offset.
*
* @param {ZoneOffset} offset - the offset, not null
* @return {ZoneRules} the zone rules, not null
*/
static of(offset) {
requireNonNull(offset, 'offset');
return new Fixed(offset);
}
//-----------------------------------------------------------------------
/**
* Checks of the zone rules are fixed, such that the offset never varies.
*
* @return {boolean} true if the time-zone is fixed and the offset never changes
*/
isFixedOffset(){
abstractMethodFail('ZoneRules.isFixedOffset');
}
//-----------------------------------------------------------------------
/**
*
* @param instantOrLocalDateTime
* @returns {ZoneOffset}
*/
offset(instantOrLocalDateTime){
if(instantOrLocalDateTime instanceof Instant){
return this.offsetOfInstant(instantOrLocalDateTime);
} else {
return this.offsetOfLocalDateTime(instantOrLocalDateTime);
}
}
/**
* Gets the offset applicable at the specified instant in these rules.
*
* The mapping from an instant to an offset is simple, there is only
* one valid offset for each instant.
* This method returns that offset.
*
* @param {Instant} instant - the instant to find the offset for, not null, but null
* may be ignored if the rules have a single offset for all instants
* @return {ZoneOffset} the offset, not null
*/
// eslint-disable-next-line no-unused-vars
offsetOfInstant(instant){
abstractMethodFail('ZoneRules.offsetInstant');
}
/**
* Gets the offset applicable at the specified epochMilli in these rules.
*
* The method is for javascript performance optimisation.
*
* @param {number} epochMilli - the epoch millisecond to find the offset for, not null, but null
* may be ignored if the rules have a single offset for all instants
* @return {ZoneOffset} the offset, not null
*/
// eslint-disable-next-line no-unused-vars
offsetOfEpochMilli(epochMilli){
abstractMethodFail('ZoneRules.offsetOfEpochMilli');
}
/**
* Gets a suitable offset for the specified local date-time in these rules.
*
* The mapping from a local date-time to an offset is not straightforward.
* There are three cases:
*
* * Normal, with one valid offset. For the vast majority of the year, the normal
* case applies, where there is a single valid offset for the local date-time.
* * Gap, with zero valid offsets. This is when clocks jump forward typically
* due to the spring daylight savings change from "winter" to "summer".
* In a gap there are local date-time values with no valid offset.
* * Overlap, with two valid offsets. This is when clocks are set back typically
* due to the autumn daylight savings change from "summer" to "winter".
* In an overlap there are local date-time values with two valid offsets.
*
* Thus, for any given local date-time there can be zero, one or two valid offsets.
* This method returns the single offset in the Normal case, and in the Gap or Overlap
* case it returns the offset before the transition.
*
* Since, in the case of Gap and Overlap, the offset returned is a "best" value, rather
* than the "correct" value, it should be treated with care. Applications that care
* about the correct offset should use a combination of this method,
* {@link getValidOffsets} and {@link getTransition}.
*
* @param {LocalDateTime} localDateTime - the local date-time to query, not null, but null
* may be ignored if the rules have a single offset for all instants
* @return {ZoneOffset} the best available offset for the local date-time, not null
*/
// eslint-disable-next-line no-unused-vars
offsetOfLocalDateTime(localDateTime){
abstractMethodFail('ZoneRules.offsetLocalDateTime');
}
/**
* Gets the offset applicable at the specified local date-time in these rules.
*
* The mapping from a local date-time to an offset is not straightforward.
* There are three cases:
*
* * Normal, with one valid offset. For the vast majority of the year, the normal
* case applies, where there is a single valid offset for the local date-time.
* * Gap, with zero valid offsets. This is when clocks jump forward typically
* due to the spring daylight savings change from "winter" to "summer".
* In a gap there are local date-time values with no valid offset.
* * Overlap, with two valid offsets. This is when clocks are set back typically
* due to the autumn daylight savings change from "summer" to "winter".
* In an overlap there are local date-time values with two valid offsets.
*
* Thus, for any given local date-time there can be zero, one or two valid offsets.
* This method returns that list of valid offsets, which is a list of size 0, 1 or 2.
* In the case where there are two offsets, the earlier offset is returned at index 0
* and the later offset at index 1.
*
* There are various ways to handle the conversion from a {@link LocalDateTime}.
* One technique, using this method, would be:
* <pre>
* List<ZoneOffset> validOffsets = rules.getOffset(localDT);
* if (validOffsets.size() == 1) {
* // Normal case: only one valid offset
* zoneOffset = validOffsets.get(0);
* } else {
* // Gap or Overlap: determine what to do from transition (which will be non-null)
* ZoneOffsetTransition trans = rules.getTransition(localDT);
* }
* </pre>
*
* In theory, it is possible for there to be more than two valid offsets.
* This would happen if clocks to be put back more than once in quick succession.
* This has never happened in the history of time-zones and thus has no special handling.
* However, if it were to happen, then the list would return more than 2 entries.
*
* @param {LocalDateTime} localDateTime - the local date-time to query for valid offsets, not null
* may be ignored if the rules have a single offset for all instants
* @return {ZoneOffset[]} the list of valid offsets, may be immutable, not null
*/
// eslint-disable-next-line no-unused-vars
validOffsets(localDateTime){
abstractMethodFail('ZoneRules.validOffsets');
}
/**
* Gets the offset transition applicable at the specified local date-time in these rules.
*
* The mapping from a local date-time to an offset is not straightforward.
* There are three cases:
*
* * Normal, with one valid offset. For the vast majority of the year, the normal
* case applies, where there is a single valid offset for the local date-time.
* * Gap, with zero valid offsets. This is when clocks jump forward typically
* due to the spring daylight savings change from "winter" to "summer".
* In a gap there are local date-time values with no valid offset.
* * Overlap, with two valid offsets. This is when clocks are set back typically
* due to the autumn daylight savings change from "summer" to "winter".
* In an overlap there are local date-time values with two valid offsets.
*
* A transition is used to model the cases of a Gap or Overlap.
* The Normal case will return null.
*
* There are various ways to handle the conversion from a {@link LocalDateTime}.
* One technique, using this method, would be:
* <pre>
* ZoneOffsetTransition trans = rules.getTransition(localDT);
* if (trans != null) {
* // Gap or Overlap: determine what to do from transition
* } else {
* // Normal case: only one valid offset
* zoneOffset = rule.getOffset(localDT);
* }
* </pre>
*
* @param {LocalDateTime} localDateTime the local date-time to query for offset transition, not null, but null
* may be ignored if the rules have a single offset for all instants
* @return {ZoneOffsetTransition} the offset transition, null if the local date-time is not in transition
*/
// eslint-disable-next-line no-unused-vars
transition(localDateTime){
abstractMethodFail('ZoneRules.transition');
}
//-----------------------------------------------------------------------
/**
* Gets the standard offset for the specified instant in this zone.
*
* This provides access to historic information on how the standard offset
* has changed over time.
* The standard offset is the offset before any daylight saving time is applied.
* This is typically the offset applicable during winter.
*
* @param {Instant} instant - the instant to find the offset information for, not null, but null
* may be ignored if the rules have a single offset for all instants
* @return {ZoneOffset} the standard offset, not null
*/
// eslint-disable-next-line no-unused-vars
standardOffset(instant){
abstractMethodFail('ZoneRules.standardOffset');
}
/**
* Gets the amount of daylight savings in use for the specified instant in this zone.
*
* This provides access to historic information on how the amount of daylight
* savings has changed over time.
* This is the difference between the standard offset and the actual offset.
* Typically the amount is zero during winter and one hour during summer.
* Time-zones are second-based, so the nanosecond part of the duration will be zero.
*
* @param {Instant} instant - the instant to find the daylight savings for, not null, but null
* may be ignored if the rules have a single offset for all instants
* @return {Duration} the difference between the standard and actual offset, not null
*/
// eslint-disable-next-line no-unused-vars
daylightSavings(instant){
abstractMethodFail('ZoneRules.daylightSavings');
// default {
// ZoneOffset standardOffset = getStandardOffset(instant);
// ZoneOffset actualOffset = getOffset(instant);
// return actualOffset.toDuration().minus(standardOffset.toDuration()).normalized();
// }
}
/**
* Checks if the specified instant is in daylight savings.
*
* This checks if the standard and actual offsets are the same at the specified instant.
*
* @param {Instant} instant - the instant to find the offset information for, not null, but null
* may be ignored if the rules have a single offset for all instants
* @return {boolean} the standard offset, not null
*/
// eslint-disable-next-line no-unused-vars
isDaylightSavings(instant) {
abstractMethodFail('ZoneRules.isDaylightSavings');
// default {
// return (getStandardOffset(instant).equals(getOffset(instant)) == false);
// }
}
/**
* Checks if the offset date-time is valid for these rules.
*
* To be valid, the local date-time must not be in a gap and the offset
* must match the valid offsets.
*
* @param {LocalDateTime} localDateTime - the date-time to check, not null, but null
* may be ignored if the rules have a single offset for all instants
* @param {ZoneOffset} offset - the offset to check, null returns false
* @return {boolean} true if the offset date-time is valid for these rules
*/
// eslint-disable-next-line no-unused-vars
isValidOffset(localDateTime, offset){
abstractMethodFail('ZoneRules.isValidOffset');
}
//-----------------------------------------------------------------------
/**
* Gets the next transition after the specified instant.
*
* This returns details of the next transition after the specified instant.
* For example, if the instant represents a point where "Summer" daylight savings time
* applies, then the method will return the transition to the next "Winter" time.
*
* @param {Instant} instant - the instant to get the next transition after, not null, but null
* may be ignored if the rules have a single offset for all instants
* @return {ZoneOffsetTransition} the next transition after the specified instant, null if this is after the last transition
*/
// eslint-disable-next-line no-unused-vars
nextTransition(instant){
abstractMethodFail('ZoneRules.nextTransition');
}
/**
* Gets the previous transition before the specified instant.
*
* This returns details of the previous transition after the specified instant.
* For example, if the instant represents a point where "summer" daylight saving time
* applies, then the method will return the transition from the previous "winter" time.
*
* @param {Instant} instant - the instant to get the previous transition after, not null, but null
* may be ignored if the rules have a single offset for all instants
* @return {ZoneOffsetTransition} the previous transition after the specified instant, null if this is before the first transition
*/
// eslint-disable-next-line no-unused-vars
previousTransition(instant){
abstractMethodFail('ZoneRules.previousTransition');
}
/**
* Gets the complete list of fully defined transitions.
*
* The complete set of transitions for this rules instance is defined by this method
* and {@link getTransitionRules}. This method returns those transitions that have
* been fully defined. These are typically historical, but may be in the future.
*
* The list will be empty for fixed offset rules and for any time-zone where there has
* only ever been a single offset. The list will also be empty if the transition rules are unknown.
*
* @return {ZoneOffsetTransition[]} an immutable list of fully defined transitions, not null
*/
transitions(){
abstractMethodFail('ZoneRules.transitions');
}
/**
* Gets the list of transition rules for years beyond those defined in the transition list.
*
* The complete set of transitions for this rules instance is defined by this method
* and {@link getTransitions}. This method returns instances of {@link ZoneOffsetTransitionRule}
* that define an algorithm for when transitions will occur.
*
* For any given {@link ZoneRules}, this list contains the transition rules for years
* beyond those years that have been fully defined. These rules typically refer to future
* daylight saving time rule changes.
*
* If the zone defines daylight savings into the future, then the list will normally
* be of size two and hold information about entering and exiting daylight savings.
* If the zone does not have daylight savings, or information about future changes
* is uncertain, then the list will be empty.
*
* The list will be empty for fixed offset rules and for any time-zone where there is no
* daylight saving time. The list will also be empty if the transition rules are unknown.
*
* @return {ZoneOffsetTransitionRule[]} an immutable list of transition rules, not null
*/
transitionRules(){
abstractMethodFail('ZoneRules.transitionRules');
}
toString(){
abstractMethodFail('ZoneRules.toString');
}
/**
* toJSON() use by JSON.stringify
* delegates to toString()
*
* @return {string}
*/
toJSON() {
return this.toString();
}
}
class Fixed extends ZoneRules{
/**
*
* @param {ZoneOffset} offset
* @private
*/
constructor(offset){
super();
this._offset = offset;
}
isFixedOffset(){
return true;
}
offsetOfInstant(){
return this._offset;
}
offsetOfEpochMilli(){
return this._offset;
}
offsetOfLocalDateTime(){
return this._offset;
}
validOffsets(){
return [this._offset];
}
transition(){
return null;
}
standardOffset(){
return this._offset;
}
daylightSavings(){
return Duration.ZERO;
}
isDaylightSavings(){
return false;
}
/**
*
* @param {LocalDateTime} localDateTime
* @param {ZoneOffset} offset
* @return {boolean}
*/
isValidOffset(localDateTime, offset) {
return this._offset.equals(offset);
}
nextTransition(){
return null;
}
previousTransition(){
return null;
}
transitions(){
return [];
}
transitionRules(){
return [];
}
//-----------------------------------------------------------------------
/**
*
* @param {*} other
* @returns {boolean}
*/
equals(other) {
if (this === other) {
return true;
}
if (other instanceof Fixed) {
return this._offset.equals(other._offset);
}
return false;
}
/**
*
* @returns {string}
*/
toString() {
return `FixedRules:${this._offset.toString()}`;
}
}

View File

@@ -0,0 +1,36 @@
/*
* @copyright (c) 2016, Philipp Thürwächter, Pattrick Hüper
* @copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
import { DateTimeException } from '../errors';
export class ZoneRulesProvider {
/**
* Gets the rules for the zone ID.
*
* This returns the latest available rules for the zone ID.
*
* This method relies on time-zone data provider files that are configured.
*
* @param {string} zoneId
* @return {ZoneRules}
*/
static getRules(zoneId){
throw new DateTimeException(`unsupported ZoneId:${zoneId}`);
}
/**
* Gets the set of available zone IDs.
*
* These zone IDs are loaded and available for use by {@link ZoneId}.
*
* @return {string[]} a modifiable copy of the set of zone IDs, not null
*/
static getAvailableZoneIds(){
return [];
}
}

2527
node_modules/@js-joda/core/typings/js-joda.d.ts generated vendored Normal file

File diff suppressed because it is too large Load Diff

953
node_modules/@js-joda/core/typings/js-joda.flow.js generated vendored Normal file
View File

@@ -0,0 +1,953 @@
/**
* Flowtype definitions for js-joda
* Generated by Flowgen from a Typescript Definition
* Flowgen v1.2.0
* Author: [Joar Wilk](http://twitter.com/joarwilk)
* Repo: http://github.com/joarwilk/flowgen
*/
declare module "js-joda" {
declare class TemporalAccessor {
get(field: TemporalField): number;
query(query: TemporalQuery): any;
range(field: TemporalField): ValueRange
}
declare class Temporal mixins TemporalAccessor {
}
declare class Clock {
fixed(fixedInstant: Instant, zoneOffset: ZoneOffset): Clock;
system(zone: ZoneId): Clock;
systemDefaultZone(): Clock;
systemUTC(): Clock;
instant(): Instant;
millis(): number;
zone(): any
}
declare class DayOfWeek mixins Temporal {
MONDAY: DayOfWeek;
TUESDAY: DayOfWeek;
WEDNESDAY: DayOfWeek;
THURSDAY: DayOfWeek;
FRIDAY: DayOfWeek;
SATURDAY: DayOfWeek;
SUNDAY: DayOfWeek;
from(temporal: TemporalAccessor): DayOfWeek; of(dayOfWeek: number): DayOfWeek;
valueOf(name: string): DayOfWeek;
values(): DayOfWeek[];
adjustInto(temporal: TemporalAdjuster): this;
equals(other: any): boolean;
getDisplayName(style: TextStyle, locale: Locale): string;
getLong(field: TemporalField): number;
isSupported(field: TemporalField): boolean;
minus(days: number): DayOfWeek;
name(): string;
ordinal(): number;
plus(days: number): DayOfWeek;
toString(): string;
value(): number
}
declare class TemporalAmount {
addTo<T>(temporal: T): T;
get(unit: TemporalUnit): number;
units(): TemporalUnit[];
subtractFrom<T>(temporal: T): T
}
declare class Duration mixins TemporalAmount {
ZERO: Duration;
between(startInclusive: Temporal, endExclusive: Temporal): Duration;
from(amount: TemporalAmount): Duration; of(amount: number, unit: TemporalUnit): Duration;
ofDays(days: number): Duration;
ofHours(hours: number): Duration;
ofMillis(millis: number): Duration;
ofMinutes(minutes: number): Duration;
ofNanos(nanos: number): Duration;
ofSeconds(seconds: number): Duration;
parse(text: string): Duration;
abs(): Duration;
addTo<T>(temporal: T): T;
compareTo(otherDuration: Duration): number;
dividedBy(divisor: number): Duration;
equals(otherDuration: any): boolean;
get(unit: TemporalUnit): number;
isNegative(): boolean;
isZero(): boolean;
minus(durationOrNumber: Duration | number, unit: ChronoUnit): Duration;
minusAmountUnit(amountToSubtract: number, unit: TemporalUnit): Duration;
minusDays(daysToSubtract: number): Duration;
minusDuration(duration: Duration): Duration;
minusHours(hoursToSubtract: number): Duration;
minusMillis(millisToSubtract: number): Duration;
minusMinutes(minutesToSubtract: number): Duration;
minusNanos(nanosToSubtract: number): Duration;
minusSeconds(secondsToSubtract: number): Duration;
multipliedBy(multiplicand: number): Duration;
nano(): number;
negated(): Duration;
plus(
durationOrNumber: Duration | number,
unitOrNumber: TemporalUnit | number): Duration;
plusAmountUnit(amountToAdd: number, unit: TemporalUnit): Duration;
plusDays(daysToAdd: number): Duration;
plusDuration(duration: Duration): Duration;
plusHours(hoursToAdd: number): Duration;
plusMillis(millisToAdd: number): Duration;
plusMinutes(minutesToAdd: number): Duration;
plusNanos(nanosToAdd: number): Duration;
plusSeconds(secondsToAdd: number): Duration;
plusSecondsNanos(secondsToAdd: number, nanosToAdd: number): Duration;
seconds(): number;
subtractFrom<T>(temporal: T): T;
toDays(): number;
toHours(): number;
toJSON(): string;
toMillis(): number;
toMinutes(): number;
toNanos(): number;
toString(): string;
units(): any;
withNanos(nanoOfSecond: number): Duration;
withSeconds(seconds: number): Duration
}
declare class Instant mixins Temporal {
EPOCH: Instant;
MIN: Instant;
MAX: Instant;
MIN_SECONDS: Instant;
MAX_SECONDS: Instant;
from(temporal: TemporalAccessor): Instant;
now(clock?: Clock): Instant;
ofEpochMicro(epochMicro: number): Instant;
ofEpochMilli(epochMilli: number): Instant;
ofEpochSecond(epochSecond: number, nanoAdjustment?: number): Instant;
parse(text: string): Instant;
adjustInto(temporal: Temporal): Temporal;
compareTo(otherInstant: Instant): number;
epochSecond(): number;
equals(otherInstant: any): boolean;
get(field: TemporalField): number;
getLong(field: TemporalField): number;
hashCode(): number;
isAfter(otherInstant: Instant): boolean;
isBefore(otherInstant: Instant): boolean;
isSupported(fieldOrUnit: TemporalField | TemporalUnit): boolean;
minus(amount: TemporalAmount): Instant;
minus(amountToSubtract: number, unit: TemporalUnit): Instant;
minusMicros(microsToSubtract: number): Instant;
minusMillis(millisToSubtract: number): Instant;
minusNanos(nanosToSubtract: number): Instant;
minusSeconds(secondsToSubtract: number): Instant;
nano(): number;
plus(amount: TemporalAmount): Instant;
plus(amountToAdd: number, unit: TemporalUnit): Instant;
plusMicros(microsToAdd: number): Instant;
plusMillis(millisToAdd: number): Instant;
plusNanos(nanosToAdd: number): Instant;
plusSeconds(secondsToAdd: number): Instant;
query(query: TemporalQuery): any;
range(field: TemporalField): ValueRange;
toEpochMilli(): number;
toString(): string;
truncatedTo(unit: TemporalUnit): Instant;
until(endExclusive: Temporal, unit: TemporalUnit): number;
with(adjuster: TemporalAdjuster): Instant;
with(field: TemporalField, newValue: number): Instant;
withTemporalAdjuster(adjuster: TemporalAdjuster): Instant
}
declare class ResolverStyle {
STRICT: ResolverStyle;
SMART: ResolverStyle;
LENIENT: ResolverStyle
}
declare class DateTimeFormatter {
ISO_LOCAL_DATE: DateTimeFormatter;
ISO_LOCAL_TIME: DateTimeFormatter;
ISO_LOCAL_DATE_TIME: DateTimeFormatter;
ISO_INSTANT: DateTimeFormatter;
ISO_OFFSET_DATE_TIME: DateTimeFormatter;
ISO_ZONED_DATE_TIME: DateTimeFormatter;
ofPattern(pattern: string): DateTimeFormatter;
parsedExcessDays(): TemporalQuery;
parsedLeapSecond(): boolean;
chronology(): any;
decimalStyle(): any;
format(temporal: TemporalAccessor): string;
locale(): any;
parse(text: string, type: TemporalQuery): TemporalAccessor;
parse1(text: string): TemporalAccessor;
parse2(text: any, type: any): any;
parseUnresolved(text: any, position: any): any;
toString(): string;
withChronology(chrono: any): any;
withLocale(locale: Locale): DateTimeFormatter;
withResolverStyle(resolverStyle: ResolverStyle): DateTimeFormatter
}
declare class DateTimeFormatterBuilder {
constructor(): this;
append(formatter: DateTimeFormatter): DateTimeFormatterBuilder;
appendFraction(
field: TemporalField,
minWidth: number,
maxWidth: number,
decimalPoint: boolean): DateTimeFormatterBuilder;
appendInstant(fractionalDigits: number): DateTimeFormatterBuilder;
appendLiteral(literal: any): DateTimeFormatterBuilder;
appendOffset(pattern: string, noOffsetText: string): DateTimeFormatterBuilder;
appendOffsetId(): DateTimeFormatterBuilder;
appendPattern(pattern: string): DateTimeFormatterBuilder;
appendValue(): DateTimeFormatterBuilder;
appendValueReduced(): DateTimeFormatterBuilder;
appendZoneId(): DateTimeFormatterBuilder;
optionalEnd(): DateTimeFormatterBuilder;
optionalStart(): DateTimeFormatterBuilder;
padNext(): DateTimeFormatterBuilder;
parseCaseInsensitive(): DateTimeFormatterBuilder;
parseCaseSensitive(): DateTimeFormatterBuilder;
parseDefaulting(field: TemporalField, value: number): DateTimeFormatterBuilder;
parseLenient(): DateTimeFormatterBuilder;
parseStrict(): DateTimeFormatterBuilder;
toFormatter(resolverStyle: ResolverStyle): DateTimeFormatter
}
declare class Chronology {
}
declare class LocalTime mixins Temporal {
MIN: LocalTime;
MAX: LocalTime;
MIDNIGHT: LocalTime;
NOON: LocalTime;
HOURS_PER_DAY: number;
MINUTES_PER_HOUR: number;
MINUTES_PER_DAY: number;
SECONDS_PER_MINUTE: number;
SECONDS_PER_HOUR: number;
SECONDS_PER_DAY: number;
MILLIS_PER_DAY: number;
MICROS_PER_DAY: number;
NANOS_PER_SECOND: number;
NANOS_PER_MINUTE: number;
NANOS_PER_HOUR: number;
NANOS_PER_DAY: number;
from(temporal: TemporalAccessor): LocalTime;
now(clockOrZone?: Clock | ZoneId): LocalTime; of(
hour?: number,
minute?: number,
second?: number,
nanoOfSecond?: number): LocalTime;
ofInstant(instant: Instant, zone?: ZoneId): LocalTime;
ofNanoOfDay(nanoOfDay: number): LocalTime;
ofSecondOfDay(secondOfDay?: number, nanoOfSecond?: number): LocalTime;
parse(text: String, formatter?: DateTimeFormatter): LocalTime;
adjustInto(temporal: TemporalAdjuster): Temporal;
atDate(date: LocalDate): LocalDateTime;
compareTo(other: LocalTime): number;
equals(other: any): boolean;
format(formatter: DateTimeFormatter): string;
get(field: ChronoField): number;
getLong(field: ChronoField): number;
hashCode(): number;
hour(): number;
isAfter(other: LocalTime): boolean;
isBefore(other: LocalTime): boolean;
isSupported(fieldOrUnit: ChronoField | ChronoUnit): boolean;
minus(amount: TemporalAmount): LocalTime;
minus(amountToSubtract: number, unit: ChronoUnit): LocalTime;
minusHours(hoursToSubtract: number): LocalTime;
minusMinutes(minutesToSubtract: number): LocalTime;
minusNanos(nanosToSubtract: number): LocalTime;
minusSeconds(secondsToSubtract: number): LocalTime;
minute(): number;
nano(): number;
plus(amount: TemporalAmount): LocalTime;
plus(amountToAdd: number, unit: TemporalUnit): LocalTime;
plusHours(hoursToAdd: number): LocalTime;
plusMinutes(minutesToAdd: number): LocalTime;
plusNanos(nanosToAdd: number): LocalTime;
plusSeconds(secondstoAdd: number): LocalTime;
query(query: TemporalQuery): any;
range(field: ChronoField): ValueRange;
second(): number;
toJSON(): string;
toNanoOfDay(): number;
toSecondOfDay(): number;
toString(): string;
truncatedTo(unit: ChronoUnit): LocalTime;
until(endExclusive: TemporalAccessor, unit: TemporalUnit): number;
with(adjuster: TemporalAdjuster): LocalTime;
with(field: TemporalField, newValue: number): LocalTime;
withHour(hour: number): LocalTime;
withMinute(minute: number): LocalTime;
withNano(nanoOfSecond: number): LocalTime;
withSecond(second: number): LocalTime;
withTemporalAdjuster(adjuster: TemporalAdjuster): LocalTime
}
declare class MathUtil {
compareNumbers(a: number, b: number): number;
floorDiv(x: number, y: number): number;
floorMod(x: number, y: number): number;
intDiv(x: number, y: number): number;
intMod(x: number, y: number): number;
parseInt(value: number): number;
roundDown(r: number): number;
safeAdd(x: number, y: number): number;
safeMultiply(x: number, y: number): number;
safeSubtract(x: number, y: number): number;
safeToInt(value: number): number;
safeZero(value: number): number;
verifyInt(value: number): void
}
declare class Month mixins Temporal {
JANUARY: Month;
FEBRUARY: Month;
MARCH: Month;
APRIL: Month;
MAY: Month;
JUNE: Month;
JULY: Month;
AUGUST: Month;
SEPTEMBER: Month;
OCTOBER: Month;
NOVEMBER: Month;
DECEMBER: Month;
from(temporal: TemporalAccessor): Month; of(month: number): Month;
values(): Month[];
adjustInto(temporal: Temporal): Temporal;
firstDayOfYear(leapYear: boolean): number;
firstMonthOfQuarter(): Month;
get(field: TemporalField): number;
getDisplayName(style: TextStyle, locale: Locale): string;
getLong(field: TemporalField): number;
isSupported(field: TemporalField): boolean;
length(leapYear: boolean): number;
maxLength(): number;
minLength(): number;
minus(months: number): Month;
plus(months: number): Month;
query(query: TemporalQuery): any;
toString(): string;
value(): number
}
declare class MonthDay mixins Temporal {
from(temporal: TemporalAccessor): MonthDay;
now(arg1?: ZoneId | Clock): MonthDay; of(monthOrNumber: Month | number, number?: number): MonthDay;
ofMonthNumber(month: Month, dayOfMonth: number): MonthDay;
ofNumberNumber(month: number, dayOfMonth: number): MonthDay;
parse(text: string, formatter?: DateTimeFormatter): MonthDay;
parseString(text: string): MonthDay;
parseStringFormatter(text: string, formatter: DateTimeFormatter): MonthDay;
adjustInto(temporal: Temporal): Temporal;
atYear(year: number): LocalDate;
compareTo(other: MonthDay): number;
dayOfMonth(): number;
equals(obj: any): boolean;
format(formatter: DateTimeFormatter): string;
get(field: TemporalField): number;
getLong(field: TemporalField): number;
isAfter(other: MonthDay): boolean;
isBefore(other: MonthDay): boolean;
isSupported(field: TemporalField): boolean;
isValidYear(year: number): boolean;
month(): Month;
monthValue(): number;
query(query: TemporalQuery): any;
range(field: TemporalField): ValueRange;
toString(): string;
with(month: Month): MonthDay;
withDayOfMonth(dayOfMonth: number): MonthDay;
withMonth(month: number): MonthDay
}
declare interface TemporalField {
}
declare class ChronoField {
NANO_OF_SECOND: ChronoField;
NANO_OF_DAY: ChronoField;
MICRO_OF_SECOND: ChronoField;
MICRO_OF_DAY: ChronoField;
MILLI_OF_SECOND: ChronoField;
MILLI_OF_DAY: ChronoField;
SECOND_OF_MINUTE: ChronoField;
SECOND_OF_DAY: ChronoField;
MINUTE_OF_HOUR: ChronoField;
MINUTE_OF_DAY: ChronoField;
HOUR_OF_AMPM: ChronoField;
CLOCK_HOUR_OF_AMPM: ChronoField;
HOUR_OF_DAY: ChronoField;
CLOCK_HOUR_OF_DAY: ChronoField;
AMPM_OF_DAY: ChronoField;
DAY_OF_WEEK: ChronoField;
ALIGNED_DAY_OF_WEEK_IN_MONTH: ChronoField;
ALIGNED_DAY_OF_WEEK_IN_YEAR: ChronoField;
DAY_OF_MONTH: ChronoField;
DAY_OF_YEAR: ChronoField;
EPOCH_DAY: ChronoField;
ALIGNED_WEEK_OF_MONTH: ChronoField;
ALIGNED_WEEK_OF_YEAR: ChronoField;
MONTH_OF_YEAR: ChronoField;
PROLEPTIC_MONTH: ChronoField;
YEAR_OF_ERA: ChronoField;
YEAR: ChronoField;
ERA: ChronoField;
INSTANT_SECONDS: ChronoField;
OFFSET_SECONDS: ChronoField;
baseUnit(): number;
checkValidIntValue(value: number): number;
checkValidValue(value: number): any;
displayName(): string;
equals(other: any): boolean;
getFrom(temporal: TemporalAccessor): number;
isDateBased(): boolean;
isTimeBased(): boolean;
name(): string;
range(): ValueRange;
rangeRefinedBy(temporal: TemporalAccessor): ValueRange;
rangeUnit(): number;
toString(): string
}
declare class TemporalUnit {
addTo<T>(temporal: T, amount: number): T;
between(temporal1: Temporal, temporal2: Temporal): number;
duration(): Duration;
isDateBased(): boolean;
isDurationEstimated(): boolean;
isSupportedBy(temporal: Temporal): boolean;
isTimeBased(): boolean
}
declare class ChronoUnit mixins TemporalUnit {
MICROS: ChronoUnit;
MILLIS: ChronoUnit;
SECONDS: ChronoUnit;
MINUTES: ChronoUnit;
HOURS: ChronoUnit;
HALF_DAYS: ChronoUnit;
DAYS: ChronoUnit;
WEEKS: ChronoUnit;
MONTHS: ChronoUnit;
YEARS: ChronoUnit;
DECADES: ChronoUnit;
CENTURIES: ChronoUnit;
MILLENNIA: ChronoUnit;
ERAS: ChronoUnit;
FOREVER: ChronoUnit;
addTo<T>(temporal: T, amount: number): T;
between(temporal1: Temporal, temporal2: Temporal): number;
compareTo(other: TemporalUnit): number;
duration(): Duration;
isDateBased(): boolean;
isDurationEstimated(): boolean;
isSupportedBy(temporal: Temporal): boolean;
isTimeBased(): boolean;
toString(): string
}
declare class IsoFields {
DAY_OF_QUARTER: IsoFields;
QUARTER_OF_YEAR: IsoFields;
WEEK_OF_WEEK_BASED_YEAR: IsoFields;
WEEK_BASED_YEAR: IsoFields;
WEEK_BASED_YEARS: IsoFields;
QUARTER_YEARS: IsoFields
}
declare class ChronoLocalDate mixins Temporal {
adjustInto(temporal: TemporalAdjuster): this;
format(formatter: DateTimeFormatter): string;
isSupported(fieldOrUnit: TemporalField | TemporalUnit): boolean
}
declare class LocalDate mixins ChronoLocalDate {
MIN: LocalDate;
MAX: LocalDate;
EPOCH_0: LocalDate;
from(temporal: TemporalAccessor): LocalDate;
now(clockOrZone?: Clock | ZoneId): LocalDate; of(year: number, month: Month | number, dayOfMonth: number): LocalDate;
ofEpochDay(epochDay: number): LocalDate;
ofInstant(instant: Instant, zoneId?: ZoneId): LocalDate;
ofYearDay(year: number, dayOfYear: number): LocalDate;
parse(text: string, formatter?: DateTimeFormatter): LocalDate;
atStartOfDay(): LocalDateTime;
atStartOfDay(zone: ZoneId): ZonedDateTime;
atStartOfDayWithZone(zone: ZoneId): ZonedDateTime;
atTime(time: LocalTime): LocalDateTime;
atTime(
hour: number,
minute: number,
second?: number,
nanoOfSecond?: number): LocalDateTime;
chronology(): Chronology;
compareTo(other: LocalDate): number;
dayOfMonth(): number;
dayOfWeek(): DayOfWeek;
dayOfYear(): number;
equals(otherDate: any): boolean;
get(field: TemporalField): number;
getLong(field: TemporalField): number;
hashCode(): number;
isAfter(other: LocalDate): boolean;
isBefore(other: LocalDate): boolean;
isEqual(other: LocalDate): boolean;
isLeapYear(): boolean;
isoWeekOfWeekyear(): number;
isoWeekyear(): number;
lengthOfMonth(): number;
lengthOfYear(): number;
minus(amount: TemporalAmount): LocalDate;
minus(amountToSubtract: number, unit: TemporalUnit): LocalDate;
minusDays(daysToSubtract: number): LocalDate;
minusMonths(monthsToSubtract: number): LocalDate;
minusWeeks(weeksToSubtract: number): LocalDate;
minusYears(yearsToSubtract: number): LocalDate;
month(): Month;
monthValue(): number;
plus(amount: TemporalAmount): LocalDate;
plus(amountToAdd: number, unit: TemporalUnit): LocalDate;
plusDays(daysToAdd: number): LocalDate;
plusMonths(monthsToAdd: number): LocalDate;
plusWeeks(weeksToAdd: number): LocalDate;
plusYears(yearsToAdd: number): LocalDate;
query(query: TemporalQuery): any;
range(field: TemporalField): ValueRange;
toEpochDay(): number;
toJSON(): string;
toString(): string;
until(endDate: TemporalAccessor): Period;
until(endExclusive: TemporalAccessor, unit: TemporalUnit): number;
with(fieldOrAdjuster: TemporalField, newValue: Number): LocalDate;
with(adjuster: TemporalAdjuster): LocalDate;
withDayOfMonth(dayOfMonth: number): LocalDate;
withDayOfYear(dayOfYear: number): LocalDate;
withFieldAndValue(field: TemporalField, newValue: number): LocalDate;
withMonth(month: Month | number): LocalDate;
withTemporalAdjuster(adjuster: TemporalAdjuster): LocalDate;
withYear(year: number): LocalDate;
year(): number
}
declare class ChronoLocalDateTime mixins Temporal {
adjustInto(temporal: any): any;
chronology(): Chronology;
toEpochSecond(offset: ZoneOffset): number;
toInstant(offset: ZoneOffset): Instant
}
declare class LocalDateTime mixins ChronoLocalDateTime {
MIN: LocalDateTime;
MAX: LocalDateTime;
from(temporal: TemporalAccessor): LocalDateTime;
now(clockOrZone?: Clock | ZoneId): LocalDateTime; of(date: LocalDate, time: LocalTime): LocalDateTime; of(
year?: number,
month?: Month | number,
dayOfMonth?: number,
hour?: number,
minute?: number,
second?: number,
nanoSecond?: number): LocalDateTime;
ofEpochSecond(epochSecond: number, offset: ZoneOffset): LocalDateTime;
ofEpochSecond(epochSecond: number, nanoOfSecond: number, offset: ZoneOffset): LocalDateTime;
ofInstant(instant: Instant, zoneId?: ZoneId): LocalDateTime;
parse(text: string, formatter?: DateTimeFormatter): LocalDateTime;
adjustInto(temporal: TemporalAdjuster): LocalDateTime;
atZone(zone: ZoneId): ZonedDateTime;
compareTo(other: LocalDateTime): number;
dayOfMonth(): number;
dayOfWeek(): DayOfWeek;
dayOfYear(): number;
equals(other: any): boolean;
format(formatter: DateTimeFormatter): string;
get(field: TemporalField): number;
getLong(field: TemporalField): number;
hashCode(): number;
hour(): number;
isAfter(other: LocalDateTime): boolean;
isBefore(other: LocalDateTime): boolean;
isEqual(other: any): boolean;
isSupported(fieldOrUnit: TemporalField | TemporalUnit): boolean;
minus(amount: TemporalAmount): LocalDateTime;
minus(amountToSubtract: number, unit: TemporalUnit): LocalDateTime;
minusDays(days: number): LocalDateTime;
minusHours(hours: number): LocalDateTime;
minusMinutes(minutes: number): LocalDateTime;
minusMonths(months: number): LocalDateTime;
minusNanos(nanos: number): LocalDateTime;
minusSeconds(seconds: number): LocalDateTime;
minusTemporalAmount(amount: TemporalAmount): LocalDateTime;
minusWeeks(weeks: number): LocalDateTime;
minusYears(years: number): LocalDateTime;
minute(): number;
month(): Month;
monthValue(): number;
nano(): number;
plus(amount: TemporalAmount): LocalDateTime;
plus(amountToAdd: number, unit: TemporalUnit): LocalDateTime;
plusDays(days: number): LocalDateTime;
plusHours(hours: number): LocalDateTime;
plusMinutes(minutes: number): LocalDateTime;
plusMonths(months: number): LocalDateTime;
plusNanos(nanos: number): LocalDateTime;
plusSeconds(seconds: number): LocalDateTime;
plusTemporalAmount(amount: TemporalAmount): LocalDateTime;
plusWeeks(weeks: number): LocalDateTime;
plusYears(years: number): LocalDateTime;
query(query: TemporalQuery): any;
range(field: TemporalField): ValueRange;
second(): number;
toJSON(): string;
toLocalDate(): LocalDate;
toLocalTime(): LocalTime;
toString(): string;
truncatedTo(unit: TemporalUnit): LocalDateTime;
until(endExclusive: Temporal, unit: TemporalUnit): number;
with(adjuster: TemporalAdjuster): LocalDateTime;
with(field: TemporalField, newValue: number): LocalDateTime;
withDayOfMonth(dayOfMonth: number): LocalDateTime;
withDayOfYear(dayOfYear: number): LocalDateTime;
withHour(hour: number): LocalDateTime;
withMinute(minute: number): LocalDateTime;
withMonth(month: number | Month): LocalDateTime;
withNano(nanoOfSecond: number): LocalDateTime;
withSecond(second: number): LocalDateTime;
withTemporalAdjuster(adjuster: TemporalAdjuster): LocalDateTime;
withYear(year: number): LocalDateTime;
year(): number
}
declare class OffsetDateTime {
}
declare class Period mixins TemporalAmount {
ZERO: Period;
between(startDate: LocalDate, endDate: LocalDate): Period;
create(years: number, months: number, days: number): Duration;
from(amount: TemporalAmount): Period; of(years: number, months: number, days: number): Period;
ofDays(days: number): Period;
ofMonths(months: number): Period;
ofWeeks(weeks: number): Period;
ofYears(years: number): Period;
parse(text: string): Period;
addTo<T>(temporal: T): T;
chronology(): IsoChronology;
days(): number;
equals(obj: any): boolean;
get(unit: TemporalUnit): number;
hashCode(): number;
isNegative(): boolean;
isZero(): boolean;
minus(amountToSubtract: TemporalAmount): Period;
minusDays(daysToSubtract: number): Period;
minusMonths(monthsToSubtract: number): Period;
minusYears(yearsToSubtract: number): Period;
months(): number;
multipliedBy(scalar: number): Period;
negated(): Period;
normalized(): Period;
plus(amountToAdd: TemporalAmount): Period;
plusDays(daysToAdd: number): Period;
plusMonths(monthsToAdd: number): Period;
plusYears(yearsToAdd: number): Period;
subtractFrom<T>(temporal: T): T;
toJSON(): string;
toString(): string;
toTotalMonths(): number;
units(): ChronoUnit[];
withDays(days: number): Period;
withMonths(months: number): Period;
withYears(years: number): Period;
years(): number
}
declare class TemporalAdjuster {
adjustInto(temporal: Temporal): Temporal
}
declare class TemporalAdjusters {
dayOfWeekInMonth(ordinal: number, dayOfWeek: DayOfWeek): TemporalAdjuster;
firstDayOfMonth(): TemporalAdjuster;
firstDayOfNextMonth(): TemporalAdjuster;
firstDayOfNextYear(): TemporalAdjuster;
firstDayOfYear(): TemporalAdjuster;
firstInMonth(dayOfWeek: DayOfWeek): TemporalAdjuster;
lastDayOfMonth(): TemporalAdjuster;
lastDayOfYear(): TemporalAdjuster;
lastInMonth(dayOfWeek: DayOfWeek): TemporalAdjuster;
next(dayOfWeek: DayOfWeek): TemporalAdjuster;
nextOrSame(dayOfWeek: DayOfWeek): TemporalAdjuster;
previous(dayOfWeek: DayOfWeek): TemporalAdjuster;
previousOrSame(dayOfWeek: DayOfWeek): TemporalAdjuster
}
declare class TemporalQueries {
chronology(): TemporalQuery;
localDate(): TemporalQuery;
localTime(): TemporalQuery;
offset(): TemporalQuery;
precision(): TemporalQuery;
zone(): TemporalQuery;
zoneId(): TemporalQuery
}
declare class TemporalQuery {
queryFrom(temporal: TemporalAccessor): any
}
declare class ValueRange {
of(min: number, max: number): ValueRange; of(min: number, maxSmallest: number, maxLargest: number): ValueRange; of(
minSmallest: number,
minLargest: number,
maxSmallest: number,
maxLargest: number): ValueRange;
checkValidIntValue(value: number, field: TemporalField): number;
checkValidValue(value: number, field: TemporalField): any;
equals(other: any): boolean;
hashCode(): number;
isFixed(): boolean;
isIntValue(): boolean;
isValidIntValue(value: number): boolean;
isValidValue(value: any): boolean;
largestMinimum(): number;
maximum(): number;
minimum(): number;
smallestMaximum(): number;
toString(): string
}
declare class Year mixins Temporal {
MIN_VALUE: number;
MAX_VALUE: number;
from(temporal: TemporalAccessor): Year;
isLeap(year: number): boolean;
now(zoneIdOrClock?: ZoneId | Clock): Year; of(isoYear: number): Year;
parse(text: string, formatter?: DateTimeFormatter): Year;
atMonth(monthOrNumber: Month | number): Year;
plus(amountOrNumber: TemporalAmount | number, unit?: TemporalUnit): Year;
minus(amountOrNumber: TemporalAmount | number, unit?: TemporalUnit): Year
}
declare class YearMonth mixins Temporal {
from(temporal: TemporalAccessor): YearMonth;
now(zoneIdOrClock?: ZoneId | Clock): YearMonth; of(year: number, monthOrNumber: Month | number): YearMonth;
parse(text: string, formatter?: DateTimeFormatter): YearMonth;
minus(amount: TemporalAmount): YearMonth;
minus(amountToSubtract: number, unit: TemporalUnit): YearMonth;
minusYears(yearsToSubtract: number): YearMonth;
minusMonths(monthsToSubtract: number): YearMonth;
plus(amount: TemporalAmount): YearMonth;
plus(amountToAdd: number, unit: TemporalUnit): YearMonth;
plusYears(yearsToAdd: number): YearMonth;
plusMonths(monthsToAdd: number): YearMonth;
with(adjuster: TemporalAdjuster): YearMonth;
with(field: TemporalField, value: number): YearMonth;
withYearMonth(newYear: number, newMonth: number): YearMonth;
withYear(year: number): YearMonth;
withMonth(month: number): YearMonth;
isSupported(fieldOrUnit: TemporalField | ChronoUnit): boolean;
year(): number;
monthValue(): number;
month(): Month;
isLeapYear(): boolean;
isValidDay(): boolean;
lengthOfMonth(): number;
lengthOfYear(): number;
atDay(dayOfMonth: number): LocalDate;
atEndOfMonth(): LocalDate;
compareTo(other: YearMonth): number;
isAfter(other: YearMonth): boolean;
isBefore(other: YearMonth): boolean;
equals(other: YearMonth): boolean;
toJSON(): string;
format(formatter: DateTimeFormatter): string
}
declare class ZoneId {
SYSTEM: ZoneId;
UTC: ZoneId;
systemDefault(): ZoneId; of(zoneId: string): ZoneId;
ofOffset(prefix: string, offset: ZoneOffset): ZoneId;
from(temporal: TemporalAccessor): ZoneId;
getAvailableZoneIds(): string[];
equals(other: any): boolean;
hashCode(): number;
id(): string;
normalized(): ZoneId;
rules(): ZoneRules;
toString(): string
}
declare class ZoneOffset mixins ZoneId {
MAX_SECONDS: ZoneOffset;
UTC: ZoneOffset;
MIN: ZoneOffset;
MAX: ZoneOffset; of(offsetId: string): ZoneOffset;
ofHours(hours: number): ZoneOffset;
ofHoursMinutes(hours: number, minutes: number): ZoneOffset;
ofHoursMinutesSeconds(hours: number, minutes: number, seconds: number): ZoneOffset;
ofTotalMinutes(totalMinutes: number): ZoneOffset;
ofTotalSeconds(totalSeconds: number): ZoneOffset;
adjustInto(temporal: Temporal): Temporal;
compareTo(other: ZoneOffset): number;
equals(obj: any): boolean;
get(field: TemporalField): number;
getLong(field: TemporalField): number;
hashCode(): number;
id(): string;
query(query: TemporalQuery): any;
rules(): ZoneRules;
toString(): string;
totalSeconds(): number
}
declare class ZoneRegion mixins ZoneId {
ofId(zoneId: string): ZoneId;
id(): string;
rules(): ZoneRules
}
declare class ZoneRules {
of(offest: ZoneOffset): ZoneRules;
isFixedOffset(): boolean;
isValidOffset(localDateTime: LocalDateTime, offset: ZoneOffset): boolean;
offset(instantOrLocalDateTime: Instant | LocalDateTime): ZoneOffset;
offsetOfEpochMilli(epochMilli: number): ZoneOffset;
offsetOfInstant(instant: Instant): ZoneOffset;
offsetOfLocalDateTime(localDateTime: LocalDateTime): ZoneOffset
}
declare class ChronoZonedDateTime mixins Temporal {
compareTo(other: ChronoZonedDateTime): number;
equals(other: any): boolean;
format(formatter: DateTimeFormatter): string;
isAfter(other: ChronoZonedDateTime): boolean;
isBefore(other: ChronoZonedDateTime): boolean;
isEqual(other: ChronoZonedDateTime): boolean;
query(query: any): any;
toEpochSecond(): number;
toInstant(): Instant
}
declare class ZonedDateTime mixins ChronoZonedDateTime {
from(temporal: TemporalAccessor): ZonedDateTime;
now(clockOrZone?: Clock | ZoneId): ZonedDateTime; of(): any; of(localDateTime: LocalDateTime, zone: ZoneId): ZonedDateTime; of(date: LocalDate, time: LocalTime, zone: ZoneId): ZonedDateTime; of(
year: number,
month: number,
dayOfMonth: number,
hour: number,
minute: number,
second: number,
nanoOfSecond: number,
zone: ZoneId): ZonedDateTime;
ofInstant(): ZonedDateTime;
ofInstant(instant: Instant, zone: ZoneId): ZonedDateTime;
ofInstant(localDateTime: LocalDateTime, offset: ZoneOffset, zone: ZoneId): ZonedDateTime;
ofLocal(
localDateTime: LocalDateTime,
zone: ZoneId,
preferredOffset: ZoneOffset): ZonedDateTime;
ofStrict(localDateTime: LocalDateTime, offset: ZoneOffset, zone: ZoneId): ZonedDateTime;
parse(text: string, formatter?: DateTimeFormatter): ZonedDateTime;
dayOfMonth(): number;
dayOfWeek(): DayOfWeek;
dayOfYear(): number;
equals(other: any): boolean;
format(formatter: DateTimeFormatter): string;
get(field: TemporalField): number;
getLong(field: TemporalField): number;
hashCode(): number;
hour(): number;
isSupported(fieldOrUnit: TemporalField | TemporalUnit): boolean;
minus(): any;
minus(amountToSubtract: number, unit: TemporalUnit): ZonedDateTime;
minusDays(days: number): ZonedDateTime;
minusHours(hours: number): ZonedDateTime;
minusMinutes(minutes: number): ZonedDateTime;
minusMonths(months: number): ZonedDateTime;
minusNanos(nanos: number): ZonedDateTime;
minusSeconds(seconds: number): ZonedDateTime;
minusTemporalAmount(amount: TemporalAmount): ZonedDateTime;
minusWeeks(weeks: number): ZonedDateTime;
minusYears(years: number): ZonedDateTime;
minute(): number;
month(): Month;
monthValue(): number;
nano(): number;
offset(): any;
plus(): any;
plus(amountToAdd: number, unit: TemporalUnit): ZonedDateTime;
plusDays(days: number): any;
plusHours(hours: number): ZonedDateTime;
plusMinutes(minutes: number): ZonedDateTime;
plusMonths(months: number): ZonedDateTime;
plusNanos(nanos: number): ZonedDateTime;
plusSeconds(seconds: number): ZonedDateTime;
plusTemporalAmount(amount: TemporalAmount): ZonedDateTime;
plusWeeks(weeks: number): any;
plusYears(years: number): ZonedDateTime;
query(query: TemporalQuery): any;
range(field: TemporalField): ValueRange;
second(): number;
toJSON(): string;
toLocalDate(): LocalDate;
toLocalDateTime(): LocalDateTime;
toLocalTime(): LocalTime;
toOffsetDateTime(): OffsetDateTime;
toString(): string;
truncatedTo(unit: TemporalUnit): ZonedDateTime;
until(endExclusive: Temporal, unit: TemporalUnit): number;
with(): any;
with(field: TemporalField, newValue: number): ZonedDateTime;
withDayOfMonth(dayOfMonth: number): ZonedDateTime;
withDayOfYear(dayOfYear: number): ZonedDateTime;
withFixedOffsetZone(): ZonedDateTime;
withHour(hour: number): ZonedDateTime;
withMinute(minute: number): ZonedDateTime;
withMonth(month: number): ZonedDateTime;
withNano(nanoOfSecond: number): ZonedDateTime;
withSecond(second: number): ZonedDateTime;
withTemporalAdjuster(adjuster: TemporalAdjuster): ZonedDateTime;
withYear(year: number): ZonedDateTime;
withZoneSameInstant(zone: ZoneId): ZonedDateTime;
withZoneSameLocal(zone: ZoneId): ZonedDateTime;
year(): number;
zone(): ZoneId
}
declare class TextStyle {
asNormal(): TextStyle;
asStandalone(): TextStyle;
isStandalone(): boolean
}
declare class Locale {
}
declare class IsoChronology {
isLeapYear(prolepticYear: number): boolean;
resolveDate(fieldValues: any, resolverStyle: any): any;
equals(other: any): boolean;
toString(): string
}
declare function nativeJs(date: Date | any, zone?: ZoneId): TemporalAccessor
declare function convert(
temporal: LocalDate | LocalDateTime | ZonedDateTime,
zone?: ZoneId): {
toDate: () => Date,
toEpochMilli: () => number
}
declare function use(plugin: Function): any;
}