1673323800
IANA time zone database access for the Julia programming language. TimeZones.jl extends the Date/DateTime support for Julia to include a new time zone aware TimeType: ZonedDateTime.
TimeZones.jl can be installed through the Julia package manager:
julia> Pkg.add("TimeZones")
For detailed installation instructions see the documentation linked above.
Author: JuliaTime
Source Code: https://github.com/JuliaTime/TimeZones.jl
License: View license
1670062091
How to Change Timezone on Ubuntu 22.04. In this guide you are going to learn how to configure or setup your own timezone on Ubuntu server.
Having a local time is necessary on your server for some cronjob or any system related processes. By default, when a server is provisioned a default timezone will get configured automatically with the Coordinated Universal Time (UTC). You can change the timezone later using the below method.
Here you will learn how to use the timedatectl
command to change timezone.
Access to server using root
or user who has sudo
privileges.
To check the configured time zone that your server uses currently you can use the following command on your Ubuntu 22.04 machine.
timedatectl
You will get an output similar to the one below.
Output
Local time: Mon 2022-05-23 01:50:57 UTC
Universal time: Mon 2022-05-23 01:50:57 UTC
RTC time: Mon 2022-05-23 01:50:57
Time zone: Etc/UTC (UTC, +0000)
System clock synchronized: yes
NTP service: active
RTC in local TZ: no
Now the time zone configured is UTC.
The system timezone is configured by creating a symbolic link of /etc/localtime
to a binary timezone identifier in the /usr/share/zoneinfo
directory.
You can also view the timezone by viewing the timezone
file created inside the etc
directory.
cat /etc/timezone
Output
Etc/UTC
Now you can proceed to change the default timezone to your location. The time zones in Ubuntu uses the “Region/City” format.
So, you need to find your region and city using the list-timezones
option with the timedatectl
command.
timedatectl list-timezones
This command outputs all the available time zones.
Output
Africa/Abidjan
Africa/Accra
Africa/Algiers
Africa/Bissau
Africa/Cairo
. . .
Press Enter
to load additional available time zones.
Once you have found your time zone you use the below format to setup your own time zone.
sudo timedatectl set-timezone your_time_zone
If your time zone is America/Los_Angeles, your format should be like this
sudo timedatectl set-timezone America/Chicago
Now you can again use the timedatectl
command to confirm the time zone update.
Output
Local time: Sun 2022-05-22 20:53:00 CDT
Universal time: Mon 2022-05-23 01:53:00 UTC
RTC time: Mon 2022-05-23 01:53:00
Time zone: America/Chicago (CDT, -0500)
System clock synchronized: yes
NTP service: active
RTC in local TZ: no
That’s all.
Now you have learned how to change time zone in your Ubuntu 22.04 machine.
Thanks for your time. If you face any problem or any feedback, please leave a comment below.
Original article source at: https://www.cloudbooklet.com/
1668174300
Universal Time using local system timezone
Experimental: passes initial tests
This module lets you have whatever it is that your local system believes is Universal Time relative to the local time zone, present, past and future. And it lets you use the things that come with Base.Dates (for the most part .. not exaustively).
If you find errors, omissions, better ways, please raise an issue here.
Asks:
Do Not store UT typed values in a jld file -- store their strings, they will be rereadable.
This is transitional -- working in multiple timezones is different.
The module requires the local system provides a Standard C compliant maketm_r().
Try UTime.ok() (not exported), if it is false is module should not be used.
This is transitional -- working in multiple timezones is different.
Offers:
function | action |
---|---|
ut() | get the current date&time as it is in UT |
ut(dtm::DateTime) | convert the local date&time dtm to UT |
localtime() | get the current date&time as it is in local time |
localtime(utm::UT) | convert the UT date&time to local time |
UT(...) | like DateTime(...) |
year(utm::UT).. | like year,month... |
Year(utm::UT).. | like Year,Month... |
format(utm,DateFormat) | like format(dt::DateTime, DateFormat) |
much other stuff | used as with DateTime |
importall UTime
exports
gmt, ut, localtime, UT # gmt is an alias for ut
exports (imported from Base.Dates)
Year, Month, Week, Day, Hour, Minute, Second, Millisecond,
year, month, week, day, hour, minute, second, millisecond,
dayofyear, dayofmonth, dayofweek, yearmonthday, yearmonth, monthday,
dayofweekofmonth, daysofweekinmonth, quarterofyear, dayofquarter,
firstdayofyear, lastdayofyear, firstdayofquarter, lastdayofquarter,
firstdayofmonth, lastdayofmonth, firstdayofweek, lastdayofweek,
daysinmonth, daysinyear, monthname, monthabbr, dayname, dayabbr,
isleapyear, format, ISOUniversalTimeFormat,
adjust, tonext, toprev, tofirst, tolast, recur,
(+), (-), (.+), (.-)
Author: J-Sarnoff
Source Code: https://github.com/J-Sarnoff/UTime.jl
License: MIT license
1665921600
Toolkit to parse, validate, manipulate, compare and display dates, time & timezones in Swift.
SwiftDate is the definitive toolchain to manipulate and display dates and time zones on all Apple platform and even on Linux and Swift Server Side frameworks like Vapor or Kitura.
Over 3 million of downloads on CocoaPods.
From simple date manipulation to complex business logic SwiftDate maybe the right choice for your next project.
2.hours + 5.minutes
...)day, hour, nearestHour, weekdayNameShort
etc.)nextWeek, nextMonth, nextWeekday, tomorrow
...)isToday, isTomorrow, isSameWeek, isNextYear
...)2.hours.toUnits(.minutes)
)and of course...
The entire library is fully documented both via XCode method inspector and a complete markdown documentation you can found below.
From simple date manipulation to complex business logic SwiftDate maybe the right choice for your next project.
Let me show to you the main features of the library:
SwiftDate can recognize all the major datetime formats automatically (ISO8601, RSS, Alt RSS, .NET, SQL, HTTP...) and you can also provide your own formats. Creating a new date has never been so easy!
// All default datetime formats (15+) are recognized automatically
let _ = "2010-05-20 15:30:00".toDate()
// You can also provide your own format!
let _ = "2010-05-20 15:30".toDate("yyyy-MM-dd HH:mm")
// All ISO8601 variants are supported too with timezone parsing!
let _ = "2017-09-17T11:59:29+02:00".toISODate()
// RSS, Extended, HTTP, SQL, .NET and all the major variants are supported!
let _ = "19 Nov 2015 22:20:40 +0100".toRSS(alt: true)
Date can be manipulated by adding or removing time components using a natural language; time unit extraction is also easy and includes the support for timezone, calendar and locales!
Manipulation can be done with standard math operators and between dates, time intervals, date components and relevant time units!
// Math operations support time units
let _ = ("2010-05-20 15:30:00".toDate() + 3.months - 2.days)
let _ = Date() + 3.hours
let _ = date1 + [.year:1, .month:2, .hour:5]
let _ = date1 + date2
// extract single time unit components from date manipulation
let over1Year = (date3 - date2).year > 1
SwiftDate include an extensive set of comparison functions; you can compare two dates by granularity, check if a date is an particular day, range and practically any other comparison you ever need.
Comparison is also available via standard math operators like (>, >=, <, <=
).
// Standard math comparison is allowed
let _ = dateA >= dateB || dateC < dateB
// Complex comparisons includes granularity support
let _ = dateA.compare(toDate: dateB, granularity: .hour) == .orderedSame
let _ = dateA.isAfterDate(dateB, orEqual: true, granularity: .month) // > until month granularity
let _ = dateC.isInRange(date: dateA, and: dateB, orEqual: true, granularity: .day) // > until day granularity
let _ = dateA.earlierDate(dateB) // earlier date
let _ = dateA.laterDate(dateB) // later date
// Check if date is close to another with a given precision
let _ = dateA.compareCloseTo(dateB, precision: 1.hours.timeInterval
// Compare for relevant events:
// .isToday, .isYesterday, .isTomorrow, .isWeekend, isNextWeek
// .isSameDay, .isMorning, .isWeekday ...
let _ = date.compare(.isToday)
let _ = date.compare(.isNight)
let _ = date.compare(.isNextWeek)
let _ = date.compare(.isThisMonth)
let _ = date.compare(.startOfWeek)
let _ = date.compare(.isNextYear)
// ...and MORE THAN 30 OTHER COMPARISONS BUILT IN
// Operation in arrays (oldestIn, newestIn, sortedByNewest, sortedByOldest...)
let _ = DateInRegion.oldestIn(list: datesArray)
let _ = DateInRegion.sortedByNewest(list: datesArray)
You can create new dates from a string, time intervals or using date components. SwiftDate offers a wide set of functions to create and derivate your dates even with random generation!
// All dates includes timezone, calendar and locales!
// Create from string
let rome = Region(calendar: Calendars.gregorian, zone: Zones.europeRome, locale: Locales.italian)
let date1 = DateInRegion("2010-01-01 00:00:00", region: rome)!
// Create date from intervals
let _ = DateInRegion(seconds: 39940, region: rome)
let _ = DateInRegion(milliseconds: 5000, region: rome)
// Date from components
let _ = DateInRegion(components: {
$0.year = 2001
$0.month = 9
$0.day = 11
$0.hour = 12
$0.minute = 0
}, region: rome)
let _ = DateInRegion(year: 2001, month: 1, day: 5, hour: 23, minute: 30, second: 0, region: rome)
// Random date generation with/without bounds
let _ = DateInRegion.randomDate(region: rome)
let _ = DateInRegion.randomDate(withinDaysBeforeToday: 5)
let _ = DateInRegion.randomDates(count: 50, between: lowerLimitDate, and: upperLimitDate, region: rome)
Date can be also generated starting from other dates; SwiftDate includes an extensive set of functions to generate. Over 20 different derivated dates can be created easily using dateAt()
function.
let _ = DateInRegion().dateAt(.endOfDay) // today at the end of the day
// Over 20 different relevant dates including .startOfDay,
// .endOfDay, .startOfWeek, .tomorrow, .nextWeekday, .nextMonth, .prevYear, .nearestMinute and many others!
let _ = dateA.nextWeekday(.friday) // the next friday after dateA
let _ = (date.dateAt(.startOfMonth) - 3.days)
let _ = dateA.compare(.endOfWeek)
// Enumerate dates in range by providing your own custom
// increment expressed in date components
let from = DateInRegion("2015-01-01 10:00:00", region: rome)!
let to = DateInRegion("2015-01-02 03:00:00", region: rome)!
let increment2 = DateComponents.create {
$0.hour = 1
$0.minute = 30
$0.second = 10
}
// generate dates in range by incrementing +1h,30m,10s each new date
let dates = DateInRegion.enumerateDates(from: fromDate2, to: toDate2, increment: increment2)
// Get all mondays in Jan 2019
let mondaysInJan2019 = Date.datesForWeekday(.monday, inMonth: 1, ofYear: 2019)
// Altering time components
let _ = dateA.dateBySet(hour: 10, min: 0, secs: 0)
// Truncating a date
let _ = dateA.dateTruncated(at: [.year,.month,.day]) // reset all time components keeping only date
// Rounding a date
let _ = dateA.dateRoundedAt(.toMins(10))
let _ = dateA.dateRoundedAt(.toFloor30Mins)
// Adding components
let _ = dateA.dateByAdding(5,.year)
// Date at the start/end of any time component
let _ = dateA.dateAtEndOf(.year) // 31 of Dec at 23:59:59
let _ = dateA.dateAtStartOf(.day) // at 00:00:00 of the same day
let _ = dateA.dateAtStartOf(.month) // at 00:00:00 of the first day of the month
You can extract components directly from dates and it includes the right value expressed in date's region (the right timezone and set locale!).
// Create a date in a region, London but with the lcoale set to IT
let london = Region(calendar: .gregorian, zone: .europeLondon, locale: .italian)
let date = DateInRegion("2018-02-05 23:14:45", format: dateFormat, region: london)!
// You can extract any of the all available time units.
// VALUES ARE EXPRESSED IN THE REGION OF THE DATE (THE RIGHT TIMEZONE).
// (you can still get the UTC/absolute value by getting the inner's absoluteDate).
let _ = date.year // 2018
let _ = date.month // 2
let _ = date.monthNameDefault // 'Febbraio' as the locale is the to IT!
let _ = date.firstDayOfWeek // 5
let _ = date.weekdayNameShort // 'Lun' as locale is the to IT
// ... all components are supported: .year, .month, .day, .hour, .minute, .second,
// .monthName, .weekday, .nearestHour, .firstDayOfWeek. .quarter and so on...
You can easily convert any date to another region (aka another calendar, locale or timezone) easily! New date contains all values expressed into the destination reason
// Conversion between timezones is easy using convertTo(region:) function
let rNY = Region(calendar: Calendars.gregorian, zone: Zones.americaNewYork, locale: Locales.english)
let rRome = Region(calendar: Calendars.gregorian, zone: Zones.europeRome, locale: Locales.italian)
let dateInNY = "2017-01-01 00:00:00".toDate(region: rNY)
let dateInRome = dateInNY?.convertTo(region: rRome)!
print(dateInRome.toString()) // "dom gen 01 06:00:00 +0100 2017\n"
// You can also convert single region's attributes
let dateInIndia = dateInNY?.convertTo(timezone: Zones.indianChristmas, locale: Locales.nepaliIndia)
print("\(dateInIndia!.toString())") // "आइत जनवरी ०१ १२:००:०० +0700 २०१७\n"
Date formatting is easy, you can specify your own format, locale or use any of the provided ones.
// Date Formatting
let london = Region(calendar: .gregorian, zone: .europeLondon, locale: .english)
let date = ... // 2017-07-22T18:27:02+02:00 in london region
let _ = date.toDotNET() // /Date(1500740822000+0200)/
let _ = date.toISODate() // 2017-07-22T18:27:02+02:00
let _ = date.toFormat("dd MMM yyyy 'at' HH:mm") // "22 July 2017 at 18:27"
// You can also easily change locale when formatting a region
let _ = date.toFormat("dd MMM", locale: .italian) // "22 Luglio"
// Time Interval Formatting as Countdown
let interval: TimeInterval = (2.hours.timeInterval) + (34.minutes.timeInterval) + (5.seconds.timeInterval)
let _ = interval.toClock() // "2:34:05"
// Time Interval Formatting by Components
let _ = interval.toString {
$0.maximumUnitCount = 4
$0.allowedUnits = [.day, .hour, .minute]
$0.collapsesLargestUnit = true
$0.unitsStyle = .abbreviated
} // "2h 34m"
Relative formatting is all new in SwiftDate; it supports 120+ languages with two different styles (.default, .twitter
), 9 flavours (.long, .longTime, .longConvenient, .short, .shortTime, .shortConvenient, .narrow, .tiny, .quantify
) and all of them are customizable as you need. The extensible format allows you to provide your own translations and rules to override the default behaviour.
// Twitter Style
let _ = (Date() - 3.minutes).toRelative(style: RelativeFormatter.twitterStyle(), locale: Locales.english) // "3m"
let _ = (Date() - 6.minutes).toRelative(style: RelativeFormatter.twitterStyle(), locale: Locales.italian) // "6 min fa"
// Default Style
let _ = (now2 - 5.hours).toRelative(style: RelativeFormatter.defaultStyle(), locale: Locales.english) // "5 hours ago"
let y = (now2 - 40.minutes).toRelative(style: RelativeFormatter.defaultStyle(), locale: Locales.italian) // "45 minuti fa"
Both DateInRegion
and Region
fully support the new Swift's Codable
protocol. This mean you can safely encode/decode them:
// Encoding/Decoding a Region
let region = Region(calendar: Calendars.gregorian, zone: Zones.europeOslo, locale: Locales.english)
let encodedJSON = try JSONEncoder().encode(region)
let decodedRegion = try JSONDecoder().decode(Region.self, from: encodedJSON)
// Encoding/Decoding a DateInRegion
let date = DateInRegion("2015-09-24T13:20:55", region: region)
let encodedDate = try JSONEncoder().encode(date)
let decodedDate = try JSONDecoder().decode(DateInRegion.self, from: encodedDate)
SwiftDate integrates the great Matthew York's DateTools module in order to support Time Periods.
See Time Periods section of the documentation.
Author: Malcommac
Source Code: https://github.com/malcommac/SwiftDate
License: MIT license
1665167040
Surgically polyfills timezone support in Intl.DateTimeFormat
API
Some browsers do not support arbitrary time zone in Intl.DateTimeFormat API (becuase its optional as per ECMA-402 standard). This polyfill is only to bring this support. Polyfill contains historical timezone data, CLDR data & tiny code to polyfill this support.
Install via nodejs:
npm i date-time-format-timezone
And then import in your code:
require('date-time-format-timezone'); // polyfill is ready
In the browser
include everything:
<script src="https://unpkg.com/date-time-format-timezone@latest/build/browserified/date-time-format-timezone-complete-min.js">
or include individual files:
<script src="https://unpkg.com/date-time-format-timezone@latest/build/browserified/date-time-format-timezone-no-data-min.js">
<script src="https://unpkg.com/date-time-format-timezone@latest/build/browserified/data/locales/locale-en-US-POSIX.js">
<script src="https://unpkg.com/date-time-format-timezone@latest/build/browserified/data/metazone.js">
<script src="https://unpkg.com/date-time-format-timezone@latest/build/browserified/data/timezones/tzdata-america-los_angeles.js">
This polyfill can add this support.
new Intl.DateTimeFormat('hi', {
timeZone: 'Asia/Calcutta',
timeZoneName:'long',
year: 'numeric',
month: 'numeric',
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
}).format(new Date());
"११/१/२०१७, पू १:२६ भारतीय मानक समय"
new Intl.DateTimeFormat('en', {
timeZone: 'America/Los_Angeles',
timeZoneName:'long',
year: 'numeric',
month: 'numeric',
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
}).format(new Date());
"1/10/2017, 12:00 PM Pacific Standard Time"
API | Support |
---|---|
Intl.DateTimeFormat | ✅ |
Date.toLocaleString | ✅ |
Date.toLocaleTimeString | ✅ |
Date.toLocaleTimeString | ✅ |
git checkout https://github.com/yahoo/date-time-format-timezone.git
npm install
grunt download
grunt
npm publish
Minified | gzipped | |
---|---|---|
complete | 2.64MB | 322KB |
top zones1 only no locale | 369.32KB | 71KB |
all zones no locale | 303.19KB | 75KB |
top zones1 top locale2 | 641.86KB | 148KB |
*1. top zones are custom listed timezones here.
*2. top locales are custom listed locales here.
Author: Formatjs
Source Code: https://github.com/formatjs/date-time-format-timezone
License: View license
1663051680
In today's post we will learn about 10 Popular JavaScript Date Libraries.
Wrangling dates and times in JavaScript can be a headache. JavaScript date libraries provide user-friendly APIs and useful utilities that alleviate some of that pain. But with so many options how do you pick the best one? In this post we delve into the world of JavaScript date libraries to help you choose.
Table of contents:
*** time ago
statement.A JavaScript date library for parsing, validating, manipulating, and formatting dates.
Moment was designed to work both in the browser and in Node.js.
All code should work in both of these environments, and all unit tests are run in both of these environments.
Currently, the following browsers are used for the ci system: Chrome on Windows XP, IE 8, 9, and 10 on Windows 7, IE 11 on Windows 10, latest Firefox on Linux, and latest Safari on OSX 10.8 and 10.11.
If you want to try the sample codes below, just open your browser's console and enter them.
npm install moment
var moment = require('moment'); // require
moment().format();
Or in ES6 syntax:
import moment from 'moment';
moment().format();
Note: if you want to work with a particular variation of moment timezone, for example using only data from 2012-2022, you will need to import it from the builds
directory like so:
import moment from 'moment-timezone/builds/moment-timezone-with-data-2012-2022';
Note: In 2.4.0, the globally exported moment object was deprecated. It will be removed in next major release.
<script src="moment.js"></script>
<script>
moment().format();
</script>
Moment.js is available on cdnjs.com and on jsDelivr.
IANA Time zone support for Moment.js
Moment-Timezone is an add-on for Moment.js. Both are considered legacy projects, now in maintenance mode. In most cases, you should choose a different library.
For more details and recommendations, please see Project Status in the Moment docs.
var june = moment("2014-06-01T12:00:00Z");
june.tz('America/Los_Angeles').format('ha z'); // 5am PDT
june.tz('America/New_York').format('ha z'); // 8am EDT
june.tz('Asia/Tokyo').format('ha z'); // 9pm JST
june.tz('Australia/Sydney').format('ha z'); // 10pm EST
var dec = moment("2014-12-01T12:00:00Z");
dec.tz('America/Los_Angeles').format('ha z'); // 4am PST
dec.tz('America/New_York').format('ha z'); // 7am EST
dec.tz('Asia/Tokyo').format('ha z'); // 9pm JST
dec.tz('Australia/Sydney').format('ha z'); // 11pm EST
Timeago is a jQuery plugin that makes it easy to support automatically updating fuzzy timestamps (e.g. "4 minutes ago" or "about 1 day ago") from ISO 8601 formatted dates and times embedded in your HTML (à la microformats).
First, load jQuery and the plugin:
<script src="jquery.min.js" type="text/javascript"></script>
<script src="jquery.timeago.js" type="text/javascript"></script>
Now, let's attach it to your timestamps on DOM ready - put this in the head section:
<script type="text/javascript">
jQuery(document).ready(function() {
$("time.timeago").timeago();
});
</script>
This will turn all <time>
elements with a class of timeago
and a datetime
attribute formatted according to the ISO 8601 standard:
<time class="timeago" datetime="2011-12-17T09:24:17Z">December 17, 2011</time>
into something like this:
<time class="timeago" datetime="2011-12-17T09:24:17Z" title="December 17, 2011">about 1 day ago</time>
<abbr>
elements (or any other HTML elements) are also supported (this is for legacy microformat support and was originally supported by the library before the time
element was introduced to HTML5):
<abbr class="timeago" title="2011-12-17T09:24:17Z">December 17, 2011</abbr>
As time passes, the timestamps will automatically update.
If you want to update a timestamp programatically later, call the update
function with a new ISO8601 timestamp of Date
object. For example:
$("time#some_id").timeago("update", "2013-12-17T09:24:17Z");
// or
$("time#some_id").timeago("update", new Date());
For more usage and examples: http://timeago.yarp.com/
For different language configurations: visit the locales
directory.
A timezone-enabled, drop-in replacement for the stock JavaScript Date. The timezoneJS.Date
object is API-compatible with JS Date, with the same getter and setter methods -- it should work fine in any code that works with normal JavaScript Dates.
The timezoneJS.Date
object gives you full-blown timezone support, independent from the timezone set on the end-user's machine running the browser. It uses the Olson zoneinfo files for its timezone data.
The constructor function and setter methods use proxy JavaScript Date objects behind the scenes, so you can use strings like '10/22/2006' with the constructor. You also get the same sensible wraparound behavior with numeric parameters (like setting a value of 14 for the month wraps around to the next March).
The other significant difference from the built-in JavaScript Date is that timezoneJS.Date
also has named properties that store the values of year, month, date, etc., so it can be directly serialized to JSON and used for data transfer.
This section shows the most common way of setting up timezone-js. In the 'Customizing' section below you can find alternative approaches.
First you'll need to include the code on your page. Both timezoneJS.Date
, and the supporting code it needs in timezoneJS.timezone
are bundled in the date.js
file in src
directory. Include the code on your page with a normal JavaScript script include, like so:
<script type="text/javascript" src="/js/timezone-js/src/date.js">
Next you'll need the Olson time zone files -- timezoneJS.Date
uses the raw Olson data to calculate timezone offsets. The Olson region files are simple, structured text data, which download quickly and parse easily. (They also compress to a very small size.)
Here is an example of how to get the Olson time zone files:
##!/bin/bash
# NOTE: Run from your webroot
# Create the /tz directory
mkdir tz
# Download the latest Olson files
curl ftp://ftp.iana.org/tz/tzdata-latest.tar.gz -o tz/tzdata-latest.tar.gz
# Expand the files
tar -xvzf tz/tzdata-latest.tar.gz -C tz
# Optionally, you can remove the downloaded archives.
rm tz/tzdata-latest.tar.gz
Then you'll need to make the files available to the timezoneJS.timezone
code, and initialize the code to parse your default region. (This will be North America if you don't change it). No sense in downloading and parsing timezone data for the entire world if you're not going to be using it.
Put your directory of Olson files somewhere under your Web server root, and point timezoneJS.timezone.zoneFileBasePath
to it. Then call the init function. Your code will look something like this:
timezoneJS.timezone.zoneFileBasePath = '/tz';
timezoneJS.timezone.init({ callback: cb });
If you use timezoneJS.Date
with Fleegix.js
, jQuery
or jQuery
-compatible libraries (like Zepto.js
), there's nothing else you need to do -- timezones for North America will be loaded and parsed on initial page load, and others will be downloaded and parsed on-the-fly, as needed. If you want to use this code with some other JavaScript toolkit, you'll need to overwrite your own transport method by setting timezoneJS.timezone.transport = someFunction
method. Take a look at test-utils.js
in spec
for an example.
NOTE: By default init()
is async so you'll need to specify a callback function such as init({ callback: cb })
. Otherwise set init({ async: false })
to turn off async.
Date is an english language date parser for node.js and the browser.
npm install date.js
Standalone is also AMD-compatible
date('10 minutes from now')
date('in 5 hours')
date('at 5pm')
date('at 12:30')
date('at 23:35')
date('in 2 days')
date('tuesday at 9am')
date('monday at 1:00am')
date('last monday at 1:00am')
date('tomorrow at 3pm')
date('yesterday at 12:30am')
date('5pm tonight')
date('tomorrow at noon')
date('next week tuesday')
date('next week tuesday at 4:30pm')
date('2 weeks from wednesday')
date('tomorrow night at 9')
date('tomorrow afternoon')
date('this morning at 9')
date('at 12:30pm')
date('tomorrow at 9 in the morning')
date('2 years from yesterday at 5pm')
date('last month')
date('2nd of January')
date('1st of March')
date('1 st of March')
date('31st of September 4:00am')
date('1st of January 4:00am')
date('9th of December 4:00am')
date('tomorrow afternoon at 4:30pm 1 month from now')
date('10 seconds ago')
date('1 minute ago')
date('2 hours ago')
date('5 weeks ago')
date('2 months ago')
date('1 year ago')
date('an hour later')
date('2w from wednesday')
date('2nd day of January')
date('two hours later')
date('a fortnight from wednesday')
date('a minute ago')
date('at 12:30')
date('at 12.30')
date('tuesday at 9')
date('tomorrow at 15')
Use this package to easily convert various time formats to milliseconds.
ms('2 days') // 172800000
ms('1d') // 86400000
ms('10h') // 36000000
ms('2.5 hrs') // 9000000
ms('2h') // 7200000
ms('1m') // 60000
ms('5s') // 5000
ms('1y') // 31557600000
ms('100') // 100
ms('-3 days') // -259200000
ms('-1h') // -3600000
ms('-200') // -200
ms(60000) // "1m"
ms(2 * 60000) // "2m"
ms(-3 * 60000) // "-3m"
ms(ms('10 hours')) // "10h"
ms(60000, { long: true }) // "1 minute"
ms(2 * 60000, { long: true }) // "2 minutes"
ms(-3 * 60000, { long: true }) // "-3 minutes"
ms(ms('10 hours'), { long: true }) // "10 hours"
Countdown.js is a library that allows developers to set countdowns for any kind of interaction. For example, if you would like to submit a form, Countdown.js allows you to set a 5 second countdown and give the user a chance to cancel the submission.
If you use bower:
bower install countdown.js
Otherwise, you can download it from here.
Begins a countdown. After duration
time has passed, the function onComplete
will be executed. Every second, the onTick
function will be executed.
Example:
var countdown = new Countdown(5, function(seconds) {
console.log(seconds); //log the number of seconds that have passed
}, function() {
console.log("Countdown complete!") //log that the countdown has complete
});
Terminates countdown.
Example:
countdown.abort();
Returns remaining time in seconds.
Example:
countdown.getRemainingTime(); //=> 4
*** time ago
statement.timeago.js is a nano library(less than
2 kb
) used to format datetime with*** time ago
statement. eg: '3 hours ago'.
ago
and time in
supported.Such as
just now
12 seconds ago
2 hours ago
3 days ago
3 weeks ago
2 years ago
in 12 seconds
in 3 minutes
in 24 days
in 6 months
npm install timeago.js
import { format, render, cancel, register } from 'timeago.js';
or import with script
tag in html file and access global variable timeago
.
<script src="dist/timeago.min.js"></script>
// format the time with locale
format('2016-06-12', 'en_US');
Lightweight date formatting and parsing (~2KB). Meant to replace parsing and formatting functionality of moment.js.
npm install fecha --save
yarn add fecha
format
accepts a Date object (or timestamp) and a string format and returns a formatted string. See below for available format tokens.
Note: format
will throw an error when passed invalid parameters
import { format } from 'fecha';
type format = (date: Date, format?: string, i18n?: I18nSettings) => str;
// Custom formats
format(new Date(2015, 10, 20), 'dddd MMMM Do, YYYY'); // 'Friday November 20th, 2015'
format(new Date(1998, 5, 3, 15, 23, 10, 350), 'YYYY-MM-DD hh:mm:ss.SSS A'); // '1998-06-03 03:23:10.350 PM'
// Named masks
format(new Date(2015, 10, 20), 'isoDate'); // '2015-11-20'
format(new Date(2015, 10, 20), 'mediumDate'); // 'Nov 20, 2015'
format(new Date(2015, 10, 20, 3, 2, 1), 'isoDateTime'); // '2015-11-20T03:02:01-05:00'
format(new Date(2015, 2, 10, 5, 30, 20), 'shortTime'); // '05:30'
// Literals
format(new Date(2001, 2, 5, 6, 7, 2, 5), '[on] MM-DD-YYYY [at] HH:mm'); // 'on 03-05-2001 at 06:07'
date-fns provides the most comprehensive, yet simple and consistent toolset for manipulating JavaScript dates in a browser & Node.js.
It's like Lodash for dates
import { compareAsc, format } from 'date-fns'
format(new Date(2014, 1, 11), 'yyyy-MM-dd')
//=> '2014-02-11'
const dates = [
new Date(1995, 6, 2),
new Date(1987, 1, 11),
new Date(1989, 6, 10),
]
dates.sort(compareAsc)
//=> [
// Wed Feb 11 1987 00:00:00,
// Mon Jul 10 1989 00:00:00,
// Sun Jul 02 1995 00:00:00
// ]
The library is available as an npm package. To install the package run:
npm install date-fns --save
# or with yarn
yarn add date-fns
Thank you for following this article.
Javascript Date Library That Will Blow Your Mind
1661867652
Oof, that’s a clunky name, but at least it’s descriptive.
This is a plugin for webpack which reduces data for moment-timezone.
Moment Timezone is a comprehensive library for working with time zones in JavaScript. But that comprehensiveness comes with a file size cost. The full time zone data file is 903KiB raw, or 36KiB minified and gzipped (as of moment-timezone
version 0.5.23
).
That’s a lot of data to send to someone’s browser, especially if you don’t need all of it. Some of the time zones have data dating back to the 19th century. Thankfully there is an API to produce a custom data bundle containing only the time zone definitions you require.
Unfortunately, if you’re building your project with webpack, you don’t get to use a custom data bundle. A webpack build uses the Node.js version of moment-timezone
, which automatically includes all the time zone data. Even if you configure Moment Timezone to use a custom data bundle at run-time, the full data file will still be present in your JavaScript bundle.
This plugin allows you to configure which time zone data you want. Any unwanted data is then automatically stripped from the compiled JS bundle at build time.
Use it in combination with the moment-locales-webpack-plugin
to further reduce the compiled JS bundle size.
Take a super-simple file which does nothing more than require('moment-timezone')
. Building this with webpack in production mode results in over 1 MiB of minified JS code.
What if you only need the default English locale, and time zone data for Australia and New Zealand from 2018 to 2028? (This is a realistic scenario from a recent project.)
Running webpack in production mode results in the following file sizes:
Configuration | Raw size | Gzipped |
---|---|---|
Default | 1164 KiB | 105 KiB |
Strip locales | 959 KiB (~82%) | 56 KiB (~53%) |
Strip tz data | 265 KiB (~23%) | 69 KiB (~66%) |
Strip locales & tz data | 60 KiB (~5%) | 20 KiB (~19%) |
(Testing done with webpack@4.28.3
, moment@2.23.0
, moment-timezone@0.5.23
.)
Even if you still need all the time zones available, reducing the data to a much smaller date range can produce significant file size savings. Building the above example file with data for all zones from 2018 to 2028 produces a file size of 288KiB, or 74KiB gzipped.
Dealing with time zones can be tricky, and bugs can pop up in unexpected places. That’s doubly true when you’re auto-removing data at build time. When using this plugin, make absolutely sure that you won’t need the data you’re removing.
For example, if you know for certain that your web site/application...
startYear
option).endYear
option).matchZones
and/or matchCountries
options).However, if you’re allowing users to choose their time zone preference — with no theoretical limit on the range of dates you’ll handle — then you’re going to need all the data you can get.
If you’re in doubt about whether to include some data, err on the side of caution and include it.
Using npm:
npm install --save-dev moment-timezone-data-webpack-plugin
Or using yarn:
yarn add --dev moment-timezone-data-webpack-plugin
Add the plugin to your webpack config file:
const MomentTimezoneDataPlugin = require('moment-timezone-data-webpack-plugin');
module.exports = {
plugins: [
new MomentTimezoneDataPlugin({
// options
}),
]
};
There are four available options to filter the time zone data. At least one option must be provided.
startYear
(integer) — Only include data from this year onwards.endYear
(integer) — Only include data up to (and including) this year.matchZones
— Only include data for time zones with names matching this value. matchZones
can be any of these types:'Australia/Sydney'
)./^Australia\//
).matchCountries
— Only include data for time zones associated with specific countries, as determined by Moment Timezone’s zonesForCountry()
API. matchCountries
works with ISO 3166 2-letter country codes, and can be any of these types:'AU'
)./^A|NZ/
).NOTE: The matchCountries
option will only work when used with moment-timezone
version 0.5.28
or later. If this option is used with a non-compliant version of moment-timezone
, an error will be thrown.
All filtering options are AND (a.k.a. conjunction) filters — that is, they become more restrictive as each one is applied. Only zone data that match all the provided filters will be added to the final output. For this reason, it’s probably safer to provide only one of matchZones
or matchCountries
; providing both is allowed, but you may not get the results you expect.
There are also some non-filtering options that can be provided to configure other behaviour around file locations.
cacheDir
(string) — A path where the generated files will be cached. If not provided, the files will be cached in an automatically-generated location.momentTimezoneContext
(regexp) — A regexp matching a context where moment-timezone
is located. The timezone file will be replaced only if it is located in this context. Other instances of the timezone file out of this context will not be touched. This is useful in case you are using a version stored outside of node_modules
(e.g. if module or vendor directory is vendor\moment-timezone
the context could be matched for example with vendor[\\/]moment-timezone$
). Defaults to /node_modules[\\/]moment-timezone$/
.This plugin has been tested with and officially supports the following dependencies:
It theoretically supports older versions of webpack (as it uses built-in webpack plugins internally), but this hasn’t been tested.
const currentYear = new Date().getFullYear();
const plugin = new MomentTimezoneDataPlugin({
startYear: currentYear - 2,
endYear: currentYear + 10,
});
const plugin = new MomentTimezoneDataPlugin({
matchZones: 'America/New_York',
});
const plugin = new MomentTimezoneDataPlugin({
// Includes 'Pacific/Auckland' and 'Pacific/Chatham'
matchCountries: 'NZ',
});
const plugin = new MomentTimezoneDataPlugin({
matchZones: /Europe\/(Belfast|London|Paris|Athens)/,
startYear: 2000,
endYear: 2030,
});
const plugin = new MomentTimezoneDataPlugin({
matchZones: [/^Australia/, 'Pacific/Auckland', 'Etc/UTC'],
startYear: 2000,
endYear: 2030,
});
const plugin = new MomentTimezoneDataPlugin({
matchCountries: ['US', 'CA'],
startYear: 2000,
endYear: 2030,
});
Author: Gilmoreorless
Source Code: https://github.com/gilmoreorless/moment-timezone-data-webpack-plugin
License: MIT License
1658985060
Phone numbers are not a big deal if you can validate the input at the time you've got a human right there. My enterprise tends not to have that ability, as we receive large files from clients with little or no validation done. Rather than abandon #s which don't validate, I wrote this to parse and normalize a string into a standard NANP phone number, possibly including an extension.
$ irb
>> require "dialable"
>> pn = Dialable::NANP.parse("+1(800)555-1212 ext 1234")
>> puts pn.to_s # Pretty output
800-555-1212 x1234
>> puts pn.to_digits # Address book friendly
8005551212 x1234
>> puts pn.to_dialable # PBX friendly
8005551212
>> puts pn.extension
1234
For v1.0.0
, the timezone syntax from dialable has changed to output tzinfo
compatible names.
Also, pn.timezones and pn.relative_timezones should do the right thing.
The YAML file with the valid area codes and easily recognizable codes (like 911) can get out of date. To update your own copy, run:
cd $(dirname $(gem which dialable)) ; cd ..
ruby ./support/make_yaml_nanpa.rb > data/dialable/nanpa.yaml
Author: Chorn
Source Code: https://github.com/chorn/dialable
License: MIT license
1645560180
Format a date with timezone:
2015-11-30T10:40:35+01:00
$ npm install --save tz-format
const format = require('tz-format');
format();
//=> '2015-11-30T10:40:35+01:00'
format(0);
//=> '2015-11-30T09:40:35+00:00'
format(new Date());
//=> '2015-11-30T10:40:35+01:00'
format(new Date(), 0);
//=> '2015-11-30T09:40:35+00:00'
format(new Date(2015, 11, 25, 11, 0, 0, 0), -1);
//=> '2015-12-25T09:00:00-01:00'
Type: date
Default: new Date()
Date to be formatted.
Type: number
Offset from UTC in hours.
Author: Samverschueren
Source Code: https://github.com/samverschueren/tz-format
License: MIT License
1644461700
With version 3.0 of tzlocal, tzlocal no longer returned pytz objects, but zoneinfo objects, which has a different API. Since 4.0, it now restored partial compatibility for pytz users through Paul Ganssle's pytz_deprecation_shim.
tzlocal 4.0 also adds an official function get_localzone_name() to get only the timezone name, instead of a timezone object. On unix, it can raise an error if you don't have a timezone name configured, where get_localzone() will succeed, so only use that if you need the timezone name.
4.0 also adds way more information on what is going wrong in your configuration when the configuration files are unclear or contradictory.
This Python module returns a tzinfo
object (with a pytz_deprecation_shim, for pytz compatibility) with the local timezone information, under Unix and Windows.
It requires Python 3.6 or later, and will use the backports.tzinfo
package, for Python 3.6 to 3.8.
This module attempts to fix a glaring hole in the pytz
and zoneinfo
modules, that there is no way to get the local timezone information, unless you know the zoneinfo name, and under several Linux distros that's hard or impossible to figure out.
With tzlocal
you only need to call get_localzone()
and you will get a tzinfo
object with the local time zone info. On some Unices you will still not get to know what the timezone name is, but you don't need that when you have the tzinfo file. However, if the timezone name is readily available it will be used.
These are the systems that are in theory supported:
- Windows 2000 and later
- Any unix-like system with a
/etc/localtime
or/usr/local/etc/localtime
If you have one of the above systems and it does not work, it's a bug. Please report it.
Please note that if you are getting a time zone called local
, this is not a bug, it's actually the main feature of tzlocal
, that even if your system does NOT have a configuration file with the zoneinfo name of your time zone, it will still work.
You can also use tzlocal
to get the name of your local timezone, but only if your system is configured to make that possible. tzlocal
looks for the timezone name in /etc/timezone
, /var/db/zoneinfo
, /etc/sysconfig/clock
and /etc/conf.d/clock
. If your /etc/localtime
is a symlink it can also extract the name from that symlink.
If you need the name of your local time zone, then please make sure your system is properly configured to allow that.
If your unix system doesn't have a timezone configured, tzlocal will default to UTC.
Load the local timezone:
>>> from tzlocal import get_localzone
>>> tz = get_localzone()
>>> tz
<DstTzInfo 'Europe/Warsaw' WMT+1:24:00 STD>
Create a local datetime:
>>> from datetime import datetime
>>> dt = datetime(2015, 4, 10, 7, 22, tzinfo=tz)
>>> dt
datetime.datetime(2015, 4, 10, 7, 22, tzinfo=<DstTzInfo 'Europe/Warsaw' CEST+2:00:00 DST>)
Lookup another timezone with zoneinfo
(backports.zoneinfo
on Python 3.8 or earlier):
>>> from zoneinfo import ZoneInfo
>>> eastern = ZoneInfo('US/Eastern')
Convert the datetime:
>>> dt.astimezone(eastern)
datetime.datetime(2015, 4, 10, 1, 22, tzinfo=<DstTzInfo 'US/Eastern' EDT-1 day, 20:00:00 DST>)
If you just want the name of the local timezone, use get_localzone_name():
>>> from tzlocal import get_localzone_name
>>> get_localzone_name()
"Europe/Warsaw"
Please note that under Unix, get_localzone_name() may fail if there is no zone configured, where get_localzone() would generally succeed.
To create a development environment, create a virtualenv and make a development installation:
$ virtualenv ve
$ source ve/bin/activation (Win32: .\ve\Scripts\activate)
(ve) $ pip install -e .[test,devenv]
To run tests, just use pytest, coverage is nice as well:
(ve) $ pytest --cov=tzlocal
(Sorry if I forgot someone)
Author: Regebro
Source Code: https://github.com/regebro/tzlocal
License: MIT License
1642902720
Date is an english language date parser for node.js and the browser. For examples and demos, see: http://matthewmueller.github.io/date/
Update: date.js now has much better NLP support thanks to @kengz
npm install date.js
Standalone is also AMD-compatible
date('10 minutes from now')
date('in 5 hours')
date('at 5pm')
date('at 12:30')
date('at 23:35')
date('in 2 days')
date('tuesday at 9am')
date('monday at 1:00am')
date('last monday at 1:00am')
date('tomorrow at 3pm')
date('yesterday at 12:30am')
date('5pm tonight')
date('tomorrow at noon')
date('next week tuesday')
date('next week tuesday at 4:30pm')
date('2 weeks from wednesday')
date('tomorrow night at 9')
date('tomorrow afternoon')
date('this morning at 9')
date('at 12:30pm')
date('tomorrow at 9 in the morning')
date('2 years from yesterday at 5pm')
date('last month')
date('2nd of January')
date('1st of March')
date('1 st of March')
date('31st of September 4:00am')
date('1st of January 4:00am')
date('9th of December 4:00am')
date('tomorrow afternoon at 4:30pm 1 month from now')
date('10 seconds ago')
date('1 minute ago')
date('2 hours ago')
date('5 weeks ago')
date('2 months ago')
date('1 year ago')
date('an hour later')
date('2w from wednesday')
date('2nd day of January')
date('two hours later')
date('a fortnight from wednesday')
date('a minute ago')
date('at 12:30')
date('at 12.30')
date('tuesday at 9')
date('tomorrow at 15')
Create a Date
from a str
. You may also supply an optional offset
to the starting date. offset
defaults to the current date and time.
To run the tests, you'll need node.js:
npm install
make test
project : date
repo age : 2 years, 10 months
active : 39 days
commits : 87
files : 17
authors :
27 Matt Mueller 31.0%
12 Bulkan Evcimen 13.8%
8 kengz 9.2%
3 Eero Norri 3.4%
2 thomas 2.3%
2 Patrick Stadler 2.3%
1 Christopher Blum 1.1%
1 Federico Rampazzo 1.1%
1 Timothy Cyrus 1.1%
1 chencheng 1.1%
1 HipsterBrown 1.1%
1 Jimmy Gaussen 1.1%
Author: MatthewMueller
Source Code: https://github.com/MatthewMueller/date
License:
1642895280
TimezoneJS.Date
A timezone-enabled, drop-in replacement for the stock JavaScript Date. The timezoneJS.Date
object is API-compatible with JS Date, with the same getter and setter methods -- it should work fine in any code that works with normal JavaScript Dates.
The timezoneJS.Date
object gives you full-blown timezone support, independent from the timezone set on the end-user's machine running the browser. It uses the Olson zoneinfo files for its timezone data.
The constructor function and setter methods use proxy JavaScript Date objects behind the scenes, so you can use strings like '10/22/2006' with the constructor. You also get the same sensible wraparound behavior with numeric parameters (like setting a value of 14 for the month wraps around to the next March).
The other significant difference from the built-in JavaScript Date is that timezoneJS.Date
also has named properties that store the values of year, month, date, etc., so it can be directly serialized to JSON and used for data transfer.
This section shows the most common way of setting up timezone-js. In the 'Customizing' section below you can find alternative approaches.
First you'll need to include the code on your page. Both timezoneJS.Date
, and the supporting code it needs in timezoneJS.timezone
are bundled in the date.js
file in src
directory. Include the code on your page with a normal JavaScript script include, like so:
<script type="text/javascript" src="/js/timezone-js/src/date.js">
Next you'll need the Olson time zone files -- timezoneJS.Date
uses the raw Olson data to calculate timezone offsets. The Olson region files are simple, structured text data, which download quickly and parse easily. (They also compress to a very small size.)
Here is an example of how to get the Olson time zone files:
##!/bin/bash
# NOTE: Run from your webroot
# Create the /tz directory
mkdir tz
# Download the latest Olson files
curl ftp://ftp.iana.org/tz/tzdata-latest.tar.gz -o tz/tzdata-latest.tar.gz
# Expand the files
tar -xvzf tz/tzdata-latest.tar.gz -C tz
# Optionally, you can remove the downloaded archives.
rm tz/tzdata-latest.tar.gz
Then you'll need to make the files available to the timezoneJS.timezone
code, and initialize the code to parse your default region. (This will be North America if you don't change it). No sense in downloading and parsing timezone data for the entire world if you're not going to be using it.
Put your directory of Olson files somewhere under your Web server root, and point timezoneJS.timezone.zoneFileBasePath
to it. Then call the init function. Your code will look something like this:
timezoneJS.timezone.zoneFileBasePath = '/tz';
timezoneJS.timezone.init({ callback: cb });
If you use timezoneJS.Date
with Fleegix.js
, jQuery
or jQuery
-compatible libraries (like Zepto.js
), there's nothing else you need to do -- timezones for North America will be loaded and parsed on initial page load, and others will be downloaded and parsed on-the-fly, as needed. If you want to use this code with some other JavaScript toolkit, you'll need to overwrite your own transport method by setting timezoneJS.timezone.transport = someFunction
method. Take a look at test-utils.js
in spec
for an example.
NOTE: By default init()
is async so you'll need to specify a callback function such as init({ callback: cb })
. Otherwise set init({ async: false })
to turn off async.
The timezoneJS.Date
constructor is compatible to the normal JavaScript Date constructor, but additional allows to pass an optional tz
(timezone). In the following cases the passed date/time is unambiguous:
timezoneJS.Date(millis, [tz])
timezoneJS.Date(Date, [tz])
timezoneJS.Date(dt_str_tz, [tz])
dt_str_tz
is a date string containing timezone information, i.e. containing Z
, T
or a timezone offset matching the regular expression /[+-][0-9]{4}/
(e.g. +0200
). The one-stop shop for cross-browser JavaScript Date parsing behavior provides detailed information about JavaScript date formats.
In the following cases the date is assumed to be a date in timezone tz
or a locale date if tz
is not provided:
timezoneJS.Date(year, mon, day, [hour], [min], [second], [tz])
timezoneJS.Date(dt_str, [tz])
dt_str
is a date string containing no timezone information.
Create a timezoneJS.Date
the same way as a normal JavaScript Date, but append a timezone parameter on the end:
var dt = new timezoneJS.Date('10/31/2008', 'America/New_York');
var dt = new timezoneJS.Date(2008, 9, 31, 11, 45, 'America/Los_Angeles');
Naturally enough, the getTimezoneOffset
method returns the timezone offset in minutes based on the timezone you set for the date.
// Pre-DST-leap
var dt = new timezoneJS.Date(2006, 9, 29, 1, 59, 'America/Los_Angeles');
dt.getTimezoneOffset(); => 420
// Post-DST-leap
var dt = new timezoneJS.Date(2006, 9, 29, 2, 0, 'America/Los_Angeles');
dt.getTimezoneOffset(); => 480
Just as you'd expect, the getTime
method gives you the UTC timestamp for the given date:
var dtA = new timezoneJS.Date(2007, 9, 31, 10, 30, 'America/Los_Angeles');
var dtB = new timezoneJS.Date(2007, 9, 31, 12, 30, 'America/Chicago');
// Same timestamp
dtA.getTime(); => 1193855400000
dtB.getTime(); => 1193855400000
You can set (or reset) the timezone using the setTimezone
method:
var dt = new timezoneJS.Date('10/31/2006', 'America/Juneau');
dt.getTimezoneOffset(); => 540
dt.setTimezone('America/Chicago');
dt.getTimezoneOffset(); => 300
dt.setTimezone('Pacific/Honolulu');
dt.getTimezoneOffset(); => 600
The getTimezone
method tells you what timezone a timezoneJS.Date
is set to:
var dt = new timezoneJS.Date('12/27/2010', 'Asia/Tokyo');
dt.getTimezone(); => 'Asia/Tokyo'
You can use getTimezoneAbbreviation
method to get timezone abbreviation:
var dt = new timezoneJS.Date('10/31/2008', 'America/New_York');
dt.getTimezoneAbbreviation(); => 'EDT'
If you don't change it, the timezone region that loads on initialization is North America (the Olson 'northamerica' file). To change that to another reqion, set timezoneJS.timezone.defaultZoneFile
to your desired region, like so:
timezoneJS.timezone.zoneFileBasePath = '/tz';
timezoneJS.timezone.defaultZoneFile = 'asia';
timezoneJS.timezone.init();
If you want to preload multiple regions, set it to an array, like this:
timezoneJS.timezone.zoneFileBasePath = '/tz';
timezoneJS.timezone.defaultZoneFile = ['asia', 'backward', 'northamerica', 'southamerica'];
timezoneJS.timezone.init();
By default the timezoneJS.Date
timezone code lazy-loads the timezone data files, pulling them down and parsing them only as needed.
For example, if you go with the out-of-the-box setup, you'll have all the North American timezones pre-loaded -- but if you were to add a date with a timezone of 'Asia/Seoul,' it would grab the 'asia' Olson file and parse it before calculating the timezone offset for that date.
You can change this behavior by changing the value of timezoneJS.timezone.loadingScheme
. The three possible values are:
timezoneJS.timezone.loadingSchemes.PRELOAD_ALL
-- this will preload all the timezone data files for all reqions up front. This setting would only make sense if you know your users will be using timezones from all around the world, and you prefer taking the up-front load time to the small on-the-fly lag from lazy loading.timezoneJS.timezone.loadingSchemes.LAZY_LOAD
-- the default. Loads some amount of data up front, then lazy-loads any other needed timezone data as needed.timezoneJS.timezone.loadingSchemes.MANUAL_LOAD
-- Preloads no data, and does no lazy loading. Use this setting if you're loading pre-parsed JSON timezone data.If you use NPM, and you want to load the time zone data synchronously, you can use one or more of the tzdata* NPM modules. That way, you do not have to download the IANA zone files manually, you can just run npm update
to get the latest data.
The tzdata module contains all time zones. There are other modules, e.g. tzdata-northamerica that contain subsets of the zones.
First, install timezone-js and one or more of the tzdata modules.
npm install timezone-js tzdata
Then, initialize timezone-js with the data:
var timezoneJS = require("timezone-js");
var tzdata = require("tzdata");
var _tz = timezoneJS.timezone;
_tz.loadingScheme = _tz.loadingSchemes.MANUAL_LOAD;
_tz.loadZoneDataFromObject(tzdata);
var dt = new timezoneJS.Date(2006, 9, 29, 1, 59, 'America/Los_Angeles');
If you know beforehand what specific cities your users are going to be using, you can reduce load times specifically by creating a pre-parsed JSON data file containing only the timezone info for those specific cities.
The src directory contains 2 command-line JavaScript scripts that can generate this kind of JSON data:
node-preparse.js
: Uses Node to preparse and populate data.preparse.js
: This script requires the Rhino (Java) JavaScript engine to run, since the stock SpiderMonkey (C) engine doesn't come with file I/O capabilities.Use the script like this:
rhino preparse.js zoneFileDirectory [exemplarCities] > outputfile.json
Or:
node node-preparse.js zoneFileDirectory [exemplarCities] > outputfile.json
The first parameter is the directory where the script can find the Olson zoneinfo files. The second (optional) param should be a comma-delimited list of timzeone cities to create the JSON data for. If that parameter isn't passed, the script will generate the JSON data for all the files.
rhino preparse.js olson_files \
"Asia/Tokyo, America/New_York, Europe/London" \
> major_cities.json
rhino preparse.js olson_files > all_cities.json
Or:
node node-preparse.js olson_files \
"Asia/Tokyo, America/New_York, Europe/London" \
> major_cities.json
node node-preparse.js olson_files > all_cities.json
Once you have your file of JSON data, set your loading scheme to timezoneJS.timezone.loadingSchemes.MANUAL_LOAD
, and load the JSON data with loadZoneJSONData
, like this:
var _tz = timezoneJS.timezone;
_tz.loadingScheme = _tz.loadingSchemes.MANUAL_LOAD;
_tz.loadZoneJSONData('/major_cities.json', true);
Since the limited set of data will be much smaller than any of the zoneinfo files, and the JSON data is deserialized with eval
or JSON.parse
, this method is significantly faster than the default setup. However, it only works if you know beforehand exactly what timezones you want to use.
The Olson timezone data files are simple, space- and linefeed-delimited data. The abundance of whitespace means they compress very, very well.
If you plan to use timezoneJS.Date
in a production Web app, it's highly recommended that you first strip the copious comments found in every Olson file, and serve compressed versions of the files to all browsers that can handle it. (Note that IE6 reports itself as able to work with gzipped data, but has numerous problems with it.)
Just to give you an idea of the difference -- merely stripping out the comments from the 'northamerica' file reduces its size by two-thirds -- from 103K to 32K. Gzipping the stripped file reduces it down to 6.5K -- probably smaller than most of the graphics in your app.
The src
directory has a sample Ruby script that you can use to strip comments from Olson data files.
This project use Jake to build. In order to see available tasks, do jake -T
. The build sequence is:
jake test:init
: Download and extract tz files to lib/tz
.jake test
: Run jasmine-node
.Feel free to fork and modify at your own will. The source code is annotated and doc can be generated with jake doc
.
Author: Mde
Source Code: https://github.com/mde/timezone-js
License:
1642880340
IANA Time zone support for Moment.js
Moment-Timezone is an add-on for Moment.js. Both are considered legacy projects, now in maintenance mode. In most cases, you should choose a different library.
For more details and recommendations, please see Project Status in the Moment docs.
Thank you.
var june = moment("2014-06-01T12:00:00Z");
june.tz('America/Los_Angeles').format('ha z'); // 5am PDT
june.tz('America/New_York').format('ha z'); // 8am EDT
june.tz('Asia/Tokyo').format('ha z'); // 9pm JST
june.tz('Australia/Sydney').format('ha z'); // 10pm EST
var dec = moment("2014-12-01T12:00:00Z");
dec.tz('America/Los_Angeles').format('ha z'); // 4am PST
dec.tz('America/New_York').format('ha z'); // 7am EST
dec.tz('Asia/Tokyo').format('ha z'); // 9pm JST
dec.tz('Australia/Sydney').format('ha z'); // 11pm EST
Author: Moment
Source Code: https://github.com/moment/moment-timezone
License: MIT License
1640512876
TimeZone
This package provides the IANA time zone database and time zone aware DateTime
class, TZDateTime
.
The current time zone database version is 2021a. See the announcement for details.
You can update to the current IANA time zone database by running tool/refresh.sh
.
TimeZone
objects require time zone data, so the first step is to load one of our time zone databases.
We provide three different APIs to load a database: one which is embedded into a Dart library, one for browsers, and one for standalone environments.
We offer three different variants of the IANA database:
This is the recommended way to initialize a time zone database for non-browser environments. Each Dart libary found in lib/data
, for example lib/data/latest.dart
, contains a single no-argument function, initializeTimeZones
.
import 'package:timezone/data/latest.dart' as tz;
void main() {
tz.initializeTimeZones();
}
To initialize the all database variant, import 'package:timezone/data/latest_all.dart'
. To initialize the 10y database variant, import 'package:timezone/data/latest_10y.dart'
.
Import package:timezone/browser.dart
library and run async function Future initializeTimeZone([String path])
.
import 'package:timezone/browser.dart' as tz;
Future<void> setup() async {
await tz.initializeTimeZone();
var detroit = tz.getLocation('America/Detroit');
var now = tz.TZDateTime.now(detroit);
}
To initialize the all database variant, call initializeTimeZone('packages/timezone/data/latest_all.tzf')
. To initialize the 10y database variant, call initializeTimeZone('packages/timezone/data/latest_10y.tzf')
.
Import package:timezone/standalone.dart
library and run async function Future initializeTimeZone([String path])
.
import 'package:timezone/standalone.dart' as tz;
Future<void> setup() async {
await tz.initializeTimeZone();
var detroit = tz.getLocation('America/Detroit');
var now = tz.TZDateTime.now(detroit);
}
Note: This method likely will not work in a Flutter environment.
To initialize the all database variant, call initializeTimeZone('data/latest_all.tzf')
. To initialize the 10y database variant, call initializeTimeZone('data/latest_10y.tzf')
.
By default, when library is initialized, local location will be UTC
.
To overwrite local location you can use setLocalLocation(Location location)
function.
Future<void> setup() async {
await tz.initializeTimeZone();
var detroit = tz.getLocation('America/Detroit');
tz.setLocalLocation(detroit);
}
The public interfaces expose several top-level functions. It is recommended then to import the libraries with a prefix (the prefix tz
is common), or to import specific members via a show
clause.
Each location in the database represents a national region where all clocks keeping local time have agreed since 1970. Locations are identified by continent or ocean and then by the name of the location, which is typically the largest city within the region. For example, America/New_York represents most of the US eastern time zone; America/Phoenix represents most of Arizona, which uses mountain time without daylight saving time (DST); America/Detroit represents most of Michigan, which uses eastern time but with different DST rules in 1975; and other entries represent smaller regions like Starke County, Indiana, which switched from central to eastern time in 1991 and switched back in 2006.
final detroit = tz.getLocation('America/Detroit');
We don't provide any functions to get locations by time zone abbreviations because of the ambiguities.
Alphabetic time zone abbreviations should not be used as unique identifiers for UTC offsets as they are ambiguous in practice. For example, "EST" denotes 5 hours behind UTC in English-speaking North America, but it denotes 10 or 11 hours ahead of UTC in Australia; and French-speaking North Americans prefer "HNE" to "EST".
TimeZone objects represents time zone and contains offset, DST flag, and name in the abbreviated form.
var timeInUtc = DateTime.utc(1995, 1, 1);
var timeZone = detroit.timeZone(timeInUtc.millisecondsSinceEpoch);
The TZDateTime
class implements the DateTime
interface from dart:core
, and contains information about location and time zone.
var date = tz.TZDateTime(detroit, 2014, 11, 17);
To convert between time zones, just create a new TZDateTime
object using from
constructor and pass Location
and DateTime
to the constructor.
var localTime = tz.DateTime(2010, 1, 1);
var detroitTime = tz.TZDateTime.from(time, detroit);
This constructor supports any objects that implement DateTime
interface, so you can pass a native DateTime
object or our TZDateTime
.
After initializing the time zone database, the timeZoneDatabase
top-level member contains all of the known time zones. Examples:
import 'package:timezone/timezone.dart' as tz;
import 'package:timezone/data/latest.dart' as tz;
void main() {
tz.initializeTimeZones();
var locations = tz.timeZoneDatabase.locations;
print(locations.length); // => 429
print(locations.keys.first); // => "Africa/Abidjan"
print(locations.keys.last); // => "US/Pacific"
}
We are using IANA Time Zone Database to build our databases.
We currently build three different database variants:
Script for updating Time Zone database, it will automatically download the IANA time zone database and compile into our native format.
$ chmod +x tool/refresh.sh
$ tool/refresh.sh
Run this command:
With Dart:
$ dart pub add timezone
With Flutter:
$ flutter pub add timezone
This will add a line like this to your package's pubspec.yaml (and run an implicit dart pub get
):
dependencies:
timezone: ^0.8.0
Alternatively, your editor might support dart pub get
or flutter pub get
. Check the docs for your editor to learn more.
Now in your Dart code, you can use:
import 'package:timezone/timezone.dart';
Download Details:
Author: srawlins
Source Code: https://github.com/srawlins/timezone
1633583160
従来のWebアプリケーションは本質的に同期しています。 ユーザーはブラウザーに表示されるWebインターフェースを操作し、ブラウザーはそのユーザー操作に基づいてサーバーに要求を返し、サーバーはユーザーの新しい表示でそれらの要求に応答します。
今日、状況は変化しました。現代のWebサイトは、数十万の訪問者からの要求を処理する必要があります。これらの要求にデータベースまたはWebサービスとの対話が含まれる場合、応答時間が長くなり、何千もの訪問者が同じリソースにアクセスしている場合、Webサイトのパフォーマンスが大幅に低下する可能性があります。 ここで非同期Webが助けになります。
非同期性を選択したときに把握できる利点のいくつかを次に示します。
このチュートリアルでは、新しい要求に応答するWebサーバーの機能を制限する長時間実行タスクを処理するWebアプリケーションを構築するときに発生する一般的な落とし穴の1つを克服する方法を説明します。
簡単な解決策は、これらの長時間実行タスクをバックグラウンドで非同期に、別のスレッドまたはプロセス内で実行し、Webサーバーを解放することです。
Redis、Flask、Celery、SocketIOなどのいくつかのコンポーネントを活用して、長時間実行されるタスクの実行をオフロードし、完了したら、クライアントにそのステータスを示すプッシュ通知を送信します。
このチュートリアルでは、コルーチンを使用してコードを同時に実行できるasyncioPythonの組み込みライブラリについては説明していません。
要件が満たされると、次のコンポーネントが機能します。
Redis:は、オープンソースの高度なKey-Valueストアであり、高性能でスケーラブルなWebアプリケーションを構築するための適切なソリューションです。それを際立たせる3つの主な特徴があります:
Redisはデータベースを完全にメモリに保持し、永続性のためにのみディスクを使用します。
多くのKey-Valueデータストアと比較すると、Redisには比較的豊富なデータ型のセットがあります。
Redisのインストールは、このチュートリアルの範囲外です。ただし、Windowsマシンにインストールするには、このクイックガイドに従うことをお勧めします。
LinuxまたはmacOSを使用している場合は、以下のコマンドのいずれかを実行すると、Redisがセットアップされます。
Ubuntu / Debian:
$ sudo apt-get install redis-server
マックOS:
$ brew install redis
$ brew services start redis
注意: このチュートリアルでは、Redisバージョン3.0.504を使用しています
セロリ:Pythonの世界で最も人気のあるバックグラウンドジョブマネージャーの1人です。リアルタイム操作に重点を置いていますが、スケジューリングもサポートしています。RedisやRabbitMQなどのいくつかのメッセージブローカーと互換性があり、プロデューサーとコンシューマーの両方として機能できます。
requirements.txt
ファイルにCeleryをインストールし ます。
注意: このチュートリアルでは、Celeryバージョン4.4.7を使用しています。
このチュートリアルでは、スキャフォールディング手法を採用し、同期通信と非同期通信の違い、および非同期通信のバリエーションを理解するために、一連のさまざまなシナリオについて説明します。
すべてのシナリオはFlaskフレームワーク内で提示されます。ただし、それらのほとんどは他のPythonフレームワーク(Django、Pyramid)に簡単に移植できます。
このチュートリアルに興味をそそられ、すぐにコードに飛び込みたいと思う 場合は、この記事で使用されているコードについて、このGithubリポジトリにアクセス してください。
私たちのアプリケーションは以下で構成されます:
app_sync.py
同期通信を紹介するプログラム 。app_async1.py
クライアントがポーリングメカニズムを使用してサーバー側プロセスのフィードバックを要求する可能性がある非同期サービス呼び出しを示すプログラム 。app_async2.py
クライアントへの自動フィードバックを伴う非同期サービス呼び出しを示すプログラム 。app_async3.py
クライアントへの自動フィードバックを伴う、スケジュール後の非同期サービス呼び出しを示すプログラム 。セットアップに飛び込みましょう。もちろん 、システムにPython3をインストールする必要があり ます。私は必要なライブラリをインストールする仮想環境を使用します(そしてあなたも間違いなくそうするべきです):
$ python -m venv async-venv
$ source async-venv/bin/activate
名前の付いたファイルを作成し、 requirements.txt
その中に次の行を追加します。
Flask==1.1.2
Flask-SocketIO==5.0.1
Celery==4.4.7
redis==3.5.3
gevent==21.1.2
gevent-websocket==0.10.1
flower==0.9.7
今それらをインストールします:
$ pip install -r requirements.txt
このチュートリアルを終了すると、フォルダー構造は次のようになります。
それがクリアされたので、実際のコードを書き始めましょう。
まず、アプリケーションの構成パラメータを次のように定義します config.py
。
#config.py
#Application configuration File
################################
#Secret key that will be used by Flask for securely signing the session cookie
# and can be used for other security related needs
SECRET_KEY = 'SECRET_KEY'
#Map to REDIS Server Port
BROKER_URL = 'redis://localhost:6379'
#Minimum interval of wait time for our task
MIN_WAIT_TIME = 1
#Maximum interval of wait time for our task
MAX_WAIT_TIME = 20
注意:簡潔にするために、これらの構成パラメーターをにハードコーディングしましたが config.py
、これらのパラメーターを別のファイル(たとえば.env
)に保存することをお勧めします 。
次に、プロジェクトの初期化ファイルを次の場所に作成します init.py
。
#init.py
from flask import Flask
#Create a flask instance
app = Flask(__name__)
#Loads flask configurations from config.py
app.secret_key = app.config['SECRET_KEY']
app.config.from_object("config")
#Setup the Flask SocketIO integration (Required only for asynchronous scenarios)
from flask_socketio import SocketIO
socketio = SocketIO(app,logger=True,engineio_logger=True,message_queue=app.config['BROKER_URL'])
コーディングに入る前に、同期通信について簡単に説明します。
で同期通信、発呼者がサービスを要求し、完全にサービスを待ち受けます。そのサービスの結果を受け取った場合にのみ、作業を続行します。タイムアウトを定義して、定義された期間内にサービスが終了しない場合、呼び出しは失敗したと見なされ、呼び出し元は続行します。
同期通信がどのように機能するかを理解するために、専用のウェイターが割り当てられたと想像してください。彼はあなたの注文を受け取り、それをキッチンに届け、そこでシェフがあなたの料理を準備するのを待ちます。この間、ウェイターは何もしていません。
次の図は、同期サービス呼び出しを示しています。
同期通信はシーケンシャルタスクに適していますが、同時タスクが多数ある場合、プログラムはスレッドを使い果たし、スレッドが使用可能になるまで新しいタスクを待機させる可能性があります。
それでは、コーディングに取り掛かりましょう。Flaskがレンダリングできるテンプレート(index.html
)を作成し、その中に次のHTMLコードを含めます。
templates/index.html
<!DOCTYPE html>
<html>
<head>
<title>Synchronicity versus Asynchronicity</title>
<link rel="stylesheet" href="{{url_for('static',filename='css/materialize.min.css')}}">
<script src="{{ url_for('static',filename='js/jquery.min.js') }}"></script>
<script src="{{ url_for('static',filename='js/socket.io.js') }}"></script>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
</head>
<body class="container">
<div class="row">
<h5>Click to start a post scheduled ansycnhronous task with automatic feedback.</h5>
</div>
<div class="card-panel">
<form method='post' id="runTaskForm" action="/runPSATask">
<div>
<input id="duration" name="duration" placeholder="Enter duration in seconds. for example: 30" type="text">
<label for="duration">Duration</label>
</div>
<button style="height:50px;width:600px" type="submit" id="runTask">Run A Post Scheduled Asynchronous Task With Automatic Feedback</button>
</form>
</div>
<div class="row">
<div id="Messages" class="red-text" style="width:800px; height:400px; overflow-y:scroll;"></div>
</div>
<script>
$(document).ready(function(){
var namespace='/runPSATask';
var url = 'http://' + document.domain + ':' + location.port + namespace;
var socket = io.connect(url);
socket.on('connect', function() {
socket.emit('join_room');
});
socket.on('msg' , function(data) {
$("#Messages").prepend('<li>'+data.msg+'</li>');
});
socket.on('status', function(data) {
////alert('socket on status ='+ data.msg);
if (data.msg == 'End') {
$("#runTask").attr("disabled",false);
};
});
});
</script>
<script>
$("#runTask").click(function(e) {
$("#runTask").attr("disabled",true);
$("#Messages").empty();
$.ajax({ type: "Post"
, url: '/runPSATask'
, data: $("#runTaskForm").serialize()
, success: function(data) {
$("#Messages").empty();
$("#Messages").prepend('<li>The Task ' + data.taskid + ' has been submitted and will execute in ' + data.duration + ' seconds. </li>');
}
});
e.preventDefault();
console.log('runPSATask complete');
});
</script>
</body>
</html>
このテンプレートには次のものが含まれます。
runTask
ルートを使用してサーバーにタスクを送信するボタン/runSyncTask
。div
idでに配置されMessages
ます。次に、app_sync.py
Flaskアプリケーションを含むというプログラムを作成し、このプログラム内に2つのルートを定義します。
"/"
Webページをレンダリングします(index.html
)"/runSyncTask"
1〜20秒の乱数を生成し、反復ごとに1秒間スリープするループを実行する、長時間実行中のタスクをシミュレートします。#app_sync.py
from flask import render_template, jsonify
from random import randint
from init import app
import tasks
#Render the predefined template index.html
@app.route("/",methods=['GET'])
def index():
return render_template('index.html')
#Defining the route for running A Synchronous Task
@app.route("/runSyncTask",methods=['POST'])
def long_sync_task():
print("Running","/runSyncTask")
#Generate a random number between MIN_WAIT_TIME and MAX_WAIT_TIME
n = randint(app.config['MIN_WAIT_TIME'],app.config['MAX_WAIT_TIME'])
#Call the function long_sync_task included within tasks.py
task = tasks.long_sync_task(n=n)
#Return the random wait time generated
return jsonify({ 'waittime': n })
if __name__ == "__main__":
app.run(debug=True)
このチュートリアルで定義されているすべてのタスクのコアロジックは、プログラム内にありますtasks.py
。
#tasks.py
import time
from celery import Celery
from celery.utils.log import get_task_logger
from flask_socketio import SocketIO
import config
# Setup the logger (compatible with celery version 4)
logger = get_task_logger(__name__)
# Setup the celery client
celery = Celery(__name__)
# Load celery configurations from celeryconfig.py
celery.config_from_object("celeryconfig")
# Setup and connect the socket instance to Redis Server
socketio = SocketIO(message_queue=config.BROKER_URL)
###############################################################################
def long_sync_task(n):
print(f"This task will take {n} seconds.")
for i in range(n):
print(f"i = {i}")
time.sleep(1)
###############################################################################
@celery.task(name = 'tasks.long_async_task')
def long_async_task(n,session):
print(f"The task of session {session} will take {n} seconds.")
for i in range(n):
print(f"i = {i}")
time.sleep(1)
###############################################################################
def send_message(event, namespace, room, message):
print("Message = ", message)
socketio.emit(event, {'msg': message}, namespace=namespace, room=room)
@celery.task(name = 'tasks.long_async_taskf')
def long_async_taskf(data):
room = data['sessionid']
namespace = data['namespase']
n = data['waittime']
#Send messages signaling the lifecycle of the task
send_message('status', namespace, room, 'Begin')
send_message('msg', namespace, room, 'Begin Task {}'.format(long_async_taskf.request.id))
send_message('msg', namespace, room, 'This task will take {} seconds'.format(n))
print(f"This task will take {n} seconds.")
for i in range(n):
msg = f"{i}"
send_message('msg', namespace, room, msg )
time.sleep(1)
send_message('msg', namespace, room, 'End Task {}'.format(long_async_taskf.request.id))
send_message('status', namespace, room, 'End')
###############################################################################
@celery.task(name = 'tasks.long_async_sch_task')
def long_async_sch_task(data):
room = data['sessionid']
namespace = data['namespase']
n = data['waittime']
send_message('status', namespace, room, 'Begin')
send_message('msg' , namespace, room, 'Begin Task {}'.format(long_async_sch_task.request.id))
send_message('msg' , namespace, room, 'This task will take {} seconds'.format(n))
print(f"This task will take {n} seconds.")
for i in range(n):
msg = f"{i}"
send_message('msg', namespace, room, msg )
time.sleep(1)
send_message('msg' , namespace, room, 'End Task {}'.format(long_async_sch_task.request.id))
send_message('status', namespace, room, 'End')
###############################################################################
このセクションでは、このlong_sync_task()
関数を同期タスクとしてのみ使用します。
app_sync.py
プログラムを実行して、同期シナリオをテストしてみましょう。
$ python app_sync.py
http://localhost:5000
Flaskインスタンスが実行されているリンクにアクセスすると、次の出力が表示されます。
「同期タスクの実行」ボタンを押して、プロセスが完了するまで待ちます。
完了すると、トリガーされたタスクに割り当てられたランダムな時間を通知するメッセージが表示されます。
同時に、サーバーがタスクを実行すると、コンソールに1秒ごとに増分された数値が表示されます。
このセクションでは、クライアントがポーリングメカニズムを使用してサーバー側プロセスのフィードバックを要求する可能性のある非同期サービス呼び出しを示します。
簡単に言うと、非同期とは、プログラムが特定のプロセスが完了するのを待たずに、関係なく続行することを意味します。
発信者が開始サービスコールが、やるES N結果をオト待ち時間。発信者は、結果を気にせずにすぐに作業を続行します。発信者が結果に関心がある場合は、後で説明するメカニズムがあります。
最も単純な非同期メッセージ交換パターンはファイアアンドフォーゲットと呼ばれ 、メッセージは送信されますがフィードバックは必要ありませんが、フィードバックが必要な場合、クライアントはポーリングメカニズムを介して結果を繰り返し要求することがあります 。
ポーリングは潜在的に高いネットワーク負荷を引き起こすため、お勧めしません。それでも、サービスプロバイダー(サーバー)がクライアントについて知る必要がないという利点があります。
次の図は、シナリオを示しています。
非同期通信は、イベントに応答する必要のあるコード(たとえば、待機を伴う時間のかかるI / Oバウンド操作)に適しています。
非同期性を選択すると、システムは同時により多くの要求を処理できるようになり、スループットが向上します。
それでは、コーディングに移りましょう。構成ファイルを使用して、セロリの初期化パラメーターを定義しますceleryconfig.py
。
#celeryconfig.py
#Celery Configuration parameters
#Map to Redis server
broker_url = 'redis://localhost:6379/0'
#Backend used to store the tasks results
result_backend = 'redis://localhost:6379/0'
#A string identifying the default serialization to use Default json
task_serializer = 'json'
result_serializer = 'json'
accept_content = ['json']
#When set to false the local system timezone is used.
enable_utc = False
#To track the started state of a task, we should explicitly enable it
task_track_started = True
#Configure Celery to use a specific time zone.
#The timezone value can be any time zone supported by the pytz library
#timezone = 'Asia/Beirut'
#enable_utc = True
Flaskがレンダリングできるテンプレートを作成します(index1.html
):
<!DOCTYPE html>
<html>
<head>
<title>Synchronicity versus Asynchronicity</title>
<link rel="stylesheet" href="{{url_for('static',filename='css/materialize.min.css')}}">
<script src="{{ url_for('static',filename='js/jquery.min.js') }}"></script>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
</head>
<body class="container">
<div class="row">
<h4>Click to start an ansycnhronous task</h4>
</div>
<div class="card-panel">
<form method='post' id="runTaskForm" action="/runAsyncTask">
<button style="height:50px;width:400px" type="submit" id="runTask">Run An Asynchronous Task</button>
</form>
<form method='post' id="getTaskResultForm" action="/getAsyncTaskResult">
<button style="height:50px;width:400px" type="submit" id="getTaskResult">Get Asynchronous Task Result</button>
</form>
</div>
<div class="row">
<div id="Messages" class="red-text" style="width:800px; height:400px; overflow-y:scroll;"></div>
</div>
<script>
$("#runTask").click(function(e) {
$("#runTask").attr("disabled",true);
$("*").css("cursor","wait");
$("#Messages").empty();
$.ajax({ type: "Post"
, url: '/runAsyncTask'
, data: $("#runTaskForm").serialize()
, success: function(data) {
$("#runTask").attr("disabled",false);
$("*").css("cursor","");
$("#Messages").append('The task ' + data.taskid + ' will be executed in asynchronous manner for ' + data.waittime + ' seconds...');
}
});
e.preventDefault();
console.log('runAsyncTask complete');
});
$("#getTaskResult").click(function(e) {
var msg = $("#Messages").text();
var taskid = msg.match("task(.*)will");
//Get The Task ID from The Messages div and create a Target URL
var vurl = '/getAsyncTaskResult?taskid=' + jQuery.trim(taskid[1]);
$.ajax({ type: "Post"
, url: vurl
, data: $("#getTaskResultForm").serialize()
, success: function(data) {
$("*").css("cursor","");
$("#Messages").append('<p> The Status of the task = ' + data.taskid + ' is ' + data.taskstatus + '</p>');
}
});
e.preventDefault();
console.log('getAsyncTaskResult complete');
});
</script>
</body>
</html>
次に、app_async1.py
Flaskアプリを含むプログラムを作成します。
#app_async1.py
from flask import render_template, jsonify, session,request
from random import randint
import uuid
import tasks
from init import app
from celery.result import AsyncResult
@app.route("/",methods=['GET'])
def index():
# create a unique ID to assign for the asynchronous task
if 'uid' not in session:
sid = str(uuid.uuid4())
session['uid'] = sid
print("Session ID stored =", sid)
return render_template('index1.html')
#Run an Asynchronous Task
@app.route("/runAsyncTask",methods=['POST'])
def long_async_task():
print("Running", "/runAsyncTask")
#Generate a random number between MIN_WAIT_TIME and MAX_WAIT_TIME
n = randint(app.config['MIN_WAIT_TIME'],app.config['MAX_WAIT_TIME'])
sid = str(session['uid'])
task = tasks.long_async_task.delay(n=n,session=sid)
#print('taskid',task.id,'sessionid',sid,'waittime',n )
return jsonify({'taskid':task.id,'sessionid':sid,'waittime':n })
#Get The Result of The Asynchronous Task
@app.route('/getAsyncTaskResult', methods=['GET', 'POST'])
def result():
task_id = request.args.get('taskid')
# grab the AsyncResult
result = AsyncResult(task_id)
# print the task id
print("Task ID = ", result.task_id)
# print the Asynchronous result status
print("Task Status = ", result.status)
return jsonify({'taskid': result.task_id, 'taskstatus': result.status})
if __name__ == "__main__":
app.run(debug=True)
このプログラムには、3つの主要なルートがあります。
"/"
:Webページをレンダリングします(index1.html
)。"/runAsyncTask"
:1〜20秒の乱数を生成する非同期タスクを呼び出してから、反復ごとに1秒間スリープするループを実行します。"/getAsyncTaskResult"
:受信したタスクIDに基づいて、タスクの状態を収集します。注意:このシナリオには、SocketIOコンポーネントは含まれていません。
このシナリオをテストして、次の手順に従ってパスを進めましょう。
redis-server.exe
ます。デフォルトのインストールまたはLinux / MacOSの場合は、RedisインスタンスがTCPポート6379で実行されていることを確認してください。$ async-venv\Scripts\celery.exe worker -A tasks --loglevel=DEBUG --concurrency=1 -P solo -f celery.logs
Linux / MacOSでは、非常によく似ています。
$ async-venv/bin/celery worker -A tasks --loglevel=DEBUG --concurrency=1 -P solo -f celery.logs
これasync-venv
が仮想環境の名前であることに注意してください。別の名前を付けた場合は、必ず自分の名前に置き換えてください。セロリが始まると、次の出力が表示されます。
プログラムで定義されたタスクtasks.py
がCeleryに反映されていることを確認してください。
$ python app_async1.py
次に、ブラウザを開いて、次のリンクにアクセスします。
[非同期タスクの実行]ボタンを押すと、新しいタスクがキューに入れられ、直接実行されます。「メッセージ」セクションに、タスクのIDとその実行時間を示すメッセージが表示されます。
[非同期タスク結果の取得]ボタンを(継続的に)押すと、その特定の時間におけるタスクの状態が収集されます。
PENDING
:実行を待機しています。STARTED
:タスクが開始されました。SUCCESS
:タスクは正常に実行されました。FAILURE
:タスクの実行により例外が発生しました。RETRY
:タスクは再試行されています。REVOKED
:タスクが取り消されました。ログファイルに含まれているセロリワーカーのログcelery.logs
を確認すると、タスクのライフサイクルに気付くでしょう。
以前のシナリオに基づいて、タスクの状態を収集するために複数のリクエストを開始することによる煩わしさを軽減するために、サーバーがタスクの状態に関してクライアントを継続的に更新できるようにするソケットテクノロジの組み込みを試みます。
実際、ソケットIOエンジンは、リアルタイムの双方向イベントベースの通信を可能にします。
これがもたらす主な利点は、ネットワークの負荷を軽減し、膨大な数のクライアントに情報を伝達するためにより効率的になることです。
次の図は、シナリオを示しています。
さらに掘り下げる前に、実行する手順について簡単に説明します。
セロリからWebブラウザーにメッセージを送り返すことができるようにするために、以下を活用します。
データ接続を効果的に管理するために、次の区分化戦略を採用します。
"/runAsyncTaskF"
このシナリオに名前空間を割り当てます。(名前空間は、単一の共有接続を介してサーバーロジックを分離するために使用されます)。それでは、コーディングに移りましょう。
index2.html
):<!DOCTYPE html>
<html>
<head>
<title>Synchronicity versus Asynchronicity</title>
<link rel="stylesheet" href="{{url_for('static',filename='css/materialize.min.css')}}">
<script src="{{ url_for('static',filename='js/jquery.min.js') }}"></script>
<script src="{{ url_for('static',filename='js/socket.io.js') }}"></script>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head>
<body class="container">
<div class="row">
<h5>Click to start an ansycnhronous task with automatic feedback.</h5>
</div>
<div class="card-panel">
<form method='post' id="runTaskForm" action="/runAsyncTask">
<button style="height:50px;width:400px" type="submit" id="runTask">Run An Asynchronous Task With Automatic Feedback</button>
</form>
</div>
<div class="row">
<div id="Messages" class="red-text" style="width:800px; height:400px; overflow-y:scroll;"></div>
</div>
<script>
$(document).ready(function() {
var namespace = '/runAsyncTaskF';
var url = 'http://' + document.domain + ':' + location.port + namespace;
var socket = io.connect(url);
socket.on('connect', function() {
////alert('socket on connect');
socket.emit('join_room');
});
socket.on('msg', function(data) {
////alert('socket on msg ='+ data.msg);
$("#Messages").prepend('<li>' + data.msg + '</li>');
});
socket.on('status', function(data) {
////alert('socket on status ='+ data.msg);
if (data.msg == 'End') {
$("#runTask").attr("disabled", false);
};
});
});
</script>
<script>
$("#runTask").click(function(e) {
$("#runTask").attr("disabled", true);
$("*").css("cursor", "wait");
$("#Messages").empty();
$.ajax({
type: "Post",
url: '/runAsyncTaskF',
data: $("#runTaskForm").serialize(),
success: function(data) {
$("*").css("cursor", "");
$("#Messages").empty();
$("#Messages").prepend('<li>The Task ' + data.taskid + ' has been submitted. </li>');
}
});
e.preventDefault();
console.log('runAsyncTaskF complete');
});
</script>
</body>
</html>
app_async2.py
Flaskアプリケーションを含むと呼ばれるプログラムを作成します。
#Gevent is a coroutine based concurrency library for Python
from gevent import monkey
#For dynamic modifications of a class or module
monkey.patch_all()
from flask import render_template, jsonify, session, request
from random import randint
import uuid
import tasks
from init import app, socketio
from flask_socketio import join_room
@app.route("/",methods=['GET'])
def index():
# create a unique session ID and store it within the Flask session
if 'uid' not in session:
sid = str(uuid.uuid4())
session['uid'] = sid
print("Session ID stored =", sid)
return render_template('index2.html')
#Run an Asynchronous Task With Automatic Feedback
@app.route("/runAsyncTaskF",methods=['POST'])
def long_async_taskf():
print("Running", "/runAsyncTaskF")
# Generate a random number between MIN_WAIT_TIME and MAX_WAIT_TIME
n = randint(app.config['MIN_WAIT_TIME'], app.config['MAX_WAIT_TIME'])
data = {}
data['sessionid'] = str(session['uid'])
data['waittime'] = n
data['namespase'] = '/runAsyncTaskF'
task = tasks.long_async_taskf.delay(data)
return jsonify({ 'taskid':task.id
,'sessionid':data['sessionid']
,'waittime':data['waittime']
,'namespace':data['namespase']
})
@socketio.on('connect', namespace='/runAsyncTaskF')
def socket_connect():
#Display message upon connecting to the namespace
print('Client Connected To NameSpace /runAsyncTaskF - ',request.sid)
@socketio.on('disconnect', namespace='/runAsyncTaskF')
def socket_connect():
# Display message upon disconnecting from the namespace
print('Client disconnected From NameSpace /runAsyncTaskF - ',request.sid)
@socketio.on('join_room', namespace='/runAsyncTaskF')
def on_room():
room = str(session['uid'])
# Display message upon joining a room specific to the session previously stored.
print(f"Socket joining room {room}")
join_room(room)
@socketio.on_error_default
def error_handler(e):
# Display message on error.
print(f"socket error: {e}, {str(request.event)}")
if __name__ == "__main__":
# Run the application with socketio integration.
socketio.run(app,debug=True)
このプログラムには、主に2つのルートがあります。
"/"
:Webページをレンダリングします(index2.html
)。"/runAsyncTaskF"
:以下を実行する非同期タスクを呼び出します。long_async_taskf()
プログラム内のそれぞれのタスクを呼び出しますtasks.py
。このシナリオを実行するには:
app_async2.py
ブラウザを開き、次のリンクにアクセスしてボタンを押すと、次のような出力が徐々に表示されます。
同時に、コンソールに次の出力が表示されます。
また
celery.logs
、タスクのライフサイクルについてファイルをいつでも確認できます。
このシナリオはシナリオ3に似ています。唯一の違いは、非同期タスクを直接実行する代わりに、このタスクがクライアントによって指定された特定の期間の後に実行されるようにスケジュールされることです。
コーディングに進みましょう。非同期タスクを実行する前に待機する時間を秒単位で表すindex3.html
新しいフィールドを使用してテンプレートを作成し"Duration"
ます。
<!DOCTYPE html>
<html>
<head>
<title>Synchronicity versus Asynchronicity</title>
<link rel="stylesheet" href="{{url_for('static',filename='css/materialize.min.css')}}">
<script src="{{ url_for('static',filename='js/jquery.min.js') }}"></script>
<script src="{{ url_for('static',filename='js/socket.io.js') }}"></script>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head>
<body class="container">
<div class="row">
<h5>Click to start a post scheduled ansycnhronous task with automatic feedback.</h5>
</div>
<div class="card-panel">
<form method='post' id="runTaskForm" action="/runPSATask">
<div>
<input id="duration" name="duration" placeholder="Enter duration in seconds. for example: 30" type="text">
<label for="duration">Duration</label>
</div>
<button style="height:50px;width:600px" type="submit" id="runTask">Run A Post Scheduled Asynchronous Task With Automatic Feedback</button>
</form>
</div>
<div class="row">
<div id="Messages" class="red-text" style="width:800px; height:400px; overflow-y:scroll;"></div>
</div>
<script>
$(document).ready(function() {
var namespace = '/runPSATask';
var url = 'http://' + document.domain + ':' + location.port + namespace;
var socket = io.connect(url);
socket.on('connect', function() {
socket.emit('join_room');
});
socket.on('msg', function(data) {
$("#Messages").prepend('<li>' + data.msg + '</li>');
});
socket.on('status', function(data) {
////alert('socket on status ='+ data.msg);
if (data.msg == 'End') {
$("#runTask").attr("disabled", false);
};
});
});
</script>
<script>
$("#runTask").click(function(e) {
$("#runTask").attr("disabled", true);
$("#Messages").empty();
$.ajax({
type: "Post",
url: '/runPSATask',
data: $("#runTaskForm").serialize(),
success: function(data) {
$("#Messages").empty();
$("#Messages").prepend('<li>The Task ' + data.taskid + ' has been submitted and will execute in ' + data.duration + ' seconds. </li>');
}
});
e.preventDefault();
console.log('runPSATask complete');
});
</script>
</body>
</html>
次に、app_async3.py
このシナリオのFlaskアプリは次のとおりです。
#app_async3.py
from gevent import monkey
monkey.patch_all()
from flask import render_template, jsonify, session, request
from random import randint
import uuid
import tasks
from init import app, socketio
from flask_socketio import join_room
@app.route("/",methods=['GET'])
def index():
# create a unique session ID
if 'uid' not in session:
sid = str(uuid.uuid4())
session['uid'] = sid
print("Session ID stored =", sid)
return render_template('index3.html')
#Run a Post Scheduled Asynchronous Task With Automatic Feedback
@app.route("/runPSATask",methods=['POST'])
def long_async_sch_task():
print("Running", "/runPSATask")
# Generate a random number between MIN_WAIT_TIME and MAX_WAIT_TIME
n = randint(app.config['MIN_WAIT_TIME'], app.config['MAX_WAIT_TIME'])
data = {}
data['sessionid'] = str(session['uid'])
data['waittime'] = n
data['namespase'] = '/runPSATask'
data['duration'] = int(request.form['duration'])
#Countdown represents the duration to wait in seconds before running the task
task = tasks.long_async_sch_task.apply_async(args=[data],countdown=data['duration'])
return jsonify({ 'taskid':task.id
,'sessionid':data['sessionid']
,'waittime': data['waittime']
,'namespace':data['namespase']
,'duration':data['duration']
})
@socketio.on('connect', namespace='/runPSATask')
def socket_connect():
print('Client Connected To NameSpace /runPSATask - ',request.sid)
@socketio.on('disconnect', namespace='/runPSATask')
def socket_connect():
print('Client disconnected From NameSpace /runPSATask - ',request.sid)
@socketio.on('join_room', namespace='/runPSATask')
def on_room():
room = str(session['uid'])
print(f"Socket joining room {room}")
join_room(room)
@socketio.on_error_default
def error_handler(e):
print(f"socket error: {e}, {str(request.event)}")
if __name__ == "__main__":
socketio.run(app,debug=True)
今回long_async_sch_task()
からタスクメソッドを使用していることに注意してくださいtasks.py
。
app_async3.py
以前と同じように実行し、ブラウザを開きます。
期間(つまり10)を入力し、ボタンを押して、スケジュール後の非同期タスクを作成します。作成されると、タスクの詳細を示すメッセージが[メッセージ]ボックスに表示されます。
期間フィールドで指定した時間待つ必要があります。タスクが実行されていることがわかります。
また、
celery.logs
ログファイルに含まれているセロリワーカーのログを復元すると、タスクのライフサイクルに気付くでしょう。
セロリタスクをより適切に監視するために、セロリ クラスターを監視および管理するためのWebベースのツールであるFlowerをインストールできます。
注意:フラワーライブラリはの一部でしたrequirements.txt
。
花を使用してセロリのタスクを表示するには、次の手順に従ってください。
$ async-venv\Scripts\flower.exe worker -A tasks --port=5555
Linux / MacOSの場合:
$ async-venv/bin/flower worker -A tasks --port=5555
コンソールに次の情報が表示されます。
アプリに戻ってタスクを実行し、ブラウザを開いて
http://localhost:5555
[タスク]タブに移動します。
タスクが完了すると、フラワーダッシュボードに次のように表示されます。
この記事が、Celeryの助けを借りて同期および非同期リクエストの概念的な基礎を得るのに役立つことを願っています。同期要求は遅くなる可能性があり、非同期要求は迅速に実行されますが、あらゆるシナリオに適切な方法を認識することが重要です。時には、彼らは一緒に働くことさえあります。
リンク: https://www.thepythoncode.com/article/async-tasks-with-celery-redis-and-flask-in-python