Giter VIP home page Giter VIP logo

datetime_helper's Introduction

The Datetime Helper

A collection of useful utilities for projects that have to deal with dates, times, and time zones, with particular utility for Rails projects that enforce the use of Zulu Time.

Features

  1. A base method called is_zulu_time?,
  2. rspec matchers be_zulu_time, be_an_iso_formatted_date, and be_an_iso_formatted_time
  3. An ActiveModel validator called zulu_time, and
  4. ActiveModel::Serializer helper methods called enforce_zulu_time and enforce_iso8601_date that allow formatting and aliasing.

Each feature can be required individually so you can use the rspec matcher, ActiveModel validator, or ActiveModel::Serializer helper in isolation.

Build Status

Requirements

  1. Ruby, Bundler, etc. The usual suspects. (Tested against Ruby 2.0.0 and up)
  2. rspec if you require 'datetime_helper/rspec'
  3. active_model if you require 'datetime_helper/active_model'
  4. active_model_serializer if you require 'datetime_helper/active_model_serialiser'

TL;DR

Zulu Time is an ISO 8601 formatted string representing a datetime but in the time zone UTC+0. This makes it trivial for client applications to display dates and times correctly in their local, or other nominated time zones.

Enforcing Zulu Time across a range of projects requires a common approach to validating incoming strings, representing the data internally, serialising the data back out into strings, and testing date and time fields.

The Datetime Helper was developed to provide that common approach, and it is available as an open source project because we believe it is generically useful.

To use

Put this in your Gemfile

gem 'datetime_helper'

Basic Zulu Time checking

You can also use this to test that a DateTime, or Time, are at UTC+0, or that a String is formatted in correct Zulu Time format.

DatetimeHelper.is_zulu_time? something

Using the be_zulu_time matcher in your RSpec tests

Put this in your spec_helper.rb or equivalent

require 'datetime_helper/rspec'

RSpec.configure do |config|
  config.include DatetimeHelper::Matchers
end

And put this in your rspec tests.

it {expect(subject[:deleted_at]).to be_zulu_time}

This can be used to expect that a DateTime, or Time, are at UTC+0, or that a String is formatted in Zulu Time.

ISO Times and Dates

Similarly to the above you can also test Time and Date strings with

  • be_an_iso_formatted_time, and
  • be_an_iso_formatted_date

Validating ActiveModel fields to ensure they hold UTC+0 datetime data

First be sure you require 'datetime_helper/active_model'

Then your model class can add:

include DatetimeHelper::Validators

validates :updated_at, zulu_time: true

This will verify that a Time is supplied at UTC+0, or that a DateTime has .zone == "+00:00", or that a String is in Zulu Time format.

Enforcing ActiveModel::Serializer Zulu Time and iso8601 Date String Formats

First be sure you require 'datetime_helper/active_model_serialiser'

Then you can put this in your serialisers:

extend DatetimeHelper::Serialisers

enforce_zulu_time :updated_at
enforce_iso8601_date :enable_date
enforce_zulu_time :published_at, :published_date

The last case will also alias the api attribute published_at to the table attribute published_date.

or if you have a bunch of 'em

extend DatetimeHelper::Serialisers

%w(updated_at deleted_at).each { |attribute| enforce_zulu_time attribute }
%w(date enable_date).each { |attribute| enforce_iso8601_date attribute }

This will ensure that the serialised output is a proper Zulu time formatted string and iso8601 formatted date string.

To build

bundle install
gem build datetime_helper.gemspec

To test

bundle install
rake

The tests offer insight into how to use these utilities.

To contribute

Contributions are encouraged. See the contribution instructions for the preferred contribution process.

License

The Datetime Helper is ยฉ 2015 Westfield Labs and is available for use under the Apache 2.0 license.

Version history

Version Comments
0.0.1 First draft โ€” only the rspec matcher
0.0.2 Added the ActiveModel validator
0.0.3 Added the ActiveModel::Serializer helper
1.0.0 Cleaned up for first official release
1.0.1 Enhanced matchers, and validator
1.0.2 Add iso8601 date format for serializers
1.0.3 Change enforce_iso8601_date to work with
date-time objects
1.0.4 Anchor strings in RSpec matchers
1.0.5 Add aliasing to serializer formatting

datetime_helper's People

Contributors

davesag avatar gwagener avatar gwshaw avatar mcinerney avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

datetime_helper's Issues

Final review for v1 release

@leondewey I'd like you to give this all one final nod before I bump the version to 1.0.0 and we ship it as an actual gem on Rubygems. @mcinerney can wire up Travis to do that automatically.

Review for

  • spelling
  • module naming
  • license

Model validates usage

What are your thoughts about changing the usage

From:
validates :updated_at, zulu_time: true

To: Something along the lines of ...

validates :updated_at, datetime_format: :zulu

I think it would make the gem a bit more flexible in the sense of using the same param to support different formats if we ever add any other date or time based validations in the future

@davesag

Add support for Leap Seconds.

From Simon on the RoRo list.

It's really just a minor detail, as NTP kind of hides leap seconds most of the time (because really, they're a pretty horrible hack), but technically speaking, sometimes the second field can contain "60" -- i.e. the minute contains 61 seconds. There's one this year, in June.

So, depending on how your system implements leap seconds, you might see:
2015-06-30T23:59:60Z

Allow DateTime strings on zulu time pattern

The is_zulu_time? method accepts a time object, a datetime object and a string time, but when we pass a string time, it fails to validate datetime strings.
This PR makes the is_zulu_time? method accept datetime strings

Add rSpec matchers for ISO Dates and Times

something like

RSpec::Matchers.define :be_an_iso_formatted_time do |expected|
  match do |time|
    !(time =~ /\d{2}:\d{2}/).nil?
  end
end

RSpec::Matchers.define :be_an_iso_formatted_date do |expected|
  match do |date|
    !(date =~ /\d{4}\-\d{2}\-\d{2}/).nil?
  end
end

Add enforce_iso8601_date

Dates do not respond to utc so the enforce_zulu_time cannot be used to ensure iso8601 format. The default format from Rails looks like Fri, 15 May 2015 when it needs to be 2015-05-15.

Improve local time testing

If the local time zone is UTC+0 we currently skip the tests that check our handling of local time. This is patently inadequate and ought to be fixed.

Without forcing a dependency on ActiveSupport I'd like to be able to change the local timezone for selected tests. A wrapper like the following provides some guidance on a way to do this.

def with_time_zone(tz_name)
  prev_tz = ENV['TZ']
  ENV['TZ'] = tz_name
  yield
ensure
  ENV['TZ'] = prev_tz
end

Specs are failing on CI due to outdated gem

We use the ActiveModel::SerializerSupport module which don't exist anymore on the newer versions of the active_model_serializers gem, so we have to use the 0.9.0 version.

Update regex to allow milliseconds.

From Simon on the Rails Oceania list.

Nice work; I actually find myself just redoing this sort of thing over and over. My only query would be how it handles leap seconds -- your regex seems to limit seconds to values 0-59.

The regex in question is

ZULU_TIME_PATTERN = /^\d{4}-[0-1][0-9]-[0-3]\d{1}T[0-2]\d{1}:[0-5]\d{1}:[0-5]\d{1}Z$/

I see no reason not to change it to

/^(\d{4})-([0-1][0-9])-([0-3]\d{1})T([0-2]\d{1}):([0-5]\d{1}):([0-5]\d{1})(\.[0-9]{1,3})?Z$/

This has the advantage of allowing the user to parse the string into chunks without going to all the trouble of using Time.parse :-) Such win!

Fix readme

In the readme it calls the serialiser method in_zulu_time but it's actually enforce_zulu_time

also

require 'datetime_helper/active_model_serialisers' ought to be require 'datetime_helper/active_model_serialiser'

Add ActiveModel::Serializer support

People writing their own serialisers need a simple way to enforce that date-time fields are rendered out in correct Zulu Time format.

On a case-by-case basis we have been doing this:

  %w(updated_at deleted_at).each do |attribute|
    define_method(attribute) do
      object.send(attribute).iso8601 unless object.send(attribute).blank?
    end
  end

I feel that could be simplified to

  %w(updated_at deleted_at).each { |attribute| in_zulu_time(attribute) }

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.