Packages
timex
3.1.13
3.7.13
3.7.12
3.7.11
3.7.9
3.7.8
3.7.7
3.7.6
3.7.5
3.7.3
3.7.2
3.7.1
3.7.0
3.6.4
3.6.3
3.6.2
retired
3.6.1
3.6.0
3.5.0
3.4.2
3.4.1
3.3.0
3.2.2
3.2.1
3.2.0
3.1.25
retired
3.1.24
3.1.23
3.1.22
3.1.21
3.1.20
3.1.19
3.1.18
3.1.17
3.1.16
3.1.15
3.1.13
3.1.12
3.1.11
3.1.10
3.1.9
3.1.8
3.1.7
3.1.6
3.1.5
3.1.4
3.1.3
3.1.2
3.1.1
3.1.0
3.0.8
3.0.7
3.0.6
3.0.5
3.0.4
3.0.3
3.0.2
3.0.1
3.0.0
2.2.1
2.1.6
2.1.5
2.1.4
2.1.3
2.1.2
2.1.1
2.1.0
2.0.0
1.0.2
1.0.1
1.0.0
1.0.0-rc4
1.0.0-rc3
1.0.0-rc2
1.0.0-rc1
1.0.0-pre
0.19.5
0.19.4
0.19.3
0.19.2
0.19.1
0.19.0
0.18.2
0.18.1
0.18.0
0.17.0
0.16.2
0.16.1
0.16.0
0.15.0
0.14.3
0.14.2
0.14.1
0.14.0
0.13.5
0.13.4
0.13.3
0.13.2
0.13.1
0.13.0
0.12.9
0.12.8
0.12.7
0.12.6
0.12.5
0.12.4
0.12.3
0.12.2
0.12.1
0.12.0
0.11.0
0.10.2
0.10.1
0.10.0
0.9.0
0.8.0
0.7.1
0.6.0
0.5.0
0.4.8
0.4.7
0.4.6
Timex is a rich, comprehensive Date/Time library for Elixir projects, with full timezone support via the :tzdata package. If you need to manipulate dates, times, datetimes, timestamps, etc., then Timex is for you!
Current section
Files
Jump to
Current section
Files
lib/calendar/julian.ex
defmodule Timex.Calendar.Julian do
@moduledoc """
This module contains functions for working with dates in the Julian calendar.
"""
require Bitwise
import Timex.Macros
alias Timex.Types
@doc """
Returns the Julian day number for the given Erlang date (gregorian)
The Julian date (JD) is a continuous count of days from 1 January 4713 BC (= -4712 January 1),
Greenwich mean noon (= 12h UT). For example, AD 1978 January 1, 0h UT is JD 2443509.5
and AD 1978 July 21, 15h UT, is JD 2443711.125.
This algorithm assumes a proleptic Gregorian calendar (i.e. dates back to year 0),
unlike the NASA or US Naval Observatory algorithm - however they align perfectly
for dates back to October 15th, 1582, which is where it starts to differ, which is
due to the fact that their algorithm assumes there is no Gregorian calendar before that
date.
"""
@spec julian_date(Types.date) :: float
def julian_date({year, month, day}),
do: julian_date(year, month, day)
@doc """
Same as julian_date/1, except takes an Erlang datetime, and returns a more precise Julian date number
"""
@spec julian_date(Types.datetime) :: float
def julian_date({{year, month, day}, {hour, minute, second}}) do
julian_date(year, month, day, hour, minute, second)
end
def julian_date(_), do: {:error, :invalid_date}
@doc """
Same as julian_date/1, except takes year/month/day as distinct arguments
"""
@spec julian_date(Types.year, Types.month, Types.day) :: float
def julian_date(year, month, day) when is_date(year, month, day) do
a = div(14 - month, 12)
y = year + 4800 - a
m = month + (12 * a) - 3
jdn = day + (((153 * m) + 2) / 5) +
(365*y) +
div(y, 4) - div(y, 100) + div(y, 400) -
32045
jdn
end
def julian_date(_,_,_), do: {:error, :invalid_date}
@doc """
Same as julian_date/1, except takes year/month/day/hour/minute/second as distinct arguments
"""
@spec julian_date(Types.year, Types.month, Types.day, Types.hour, Types.minute, Types.second) :: float
def julian_date(year, month, day, hour, minute, second)
when is_datetime(year, month, day, hour, minute, second) do
jdn = julian_date(year, month, day)
jdn + div(hour - 12, 24) + div(minute, 1440) + div(second, 86400)
end
def julian_date(_,_,_,_,_,_), do: {:error, :invalid_datetime}
@doc """
Returns the day of the week, starting with 0 for Sunday, or 1 for Monday
"""
@spec day_of_week(Types.date, :sun | :mon) :: Types.weekday
def day_of_week({year, month, day}, weekstart),
do: day_of_week(year, month, day, weekstart)
@doc """
Same as day_of_week/1, except takes year/month/day as distinct arguments
"""
@spec day_of_week(Types.year, Types.month, Types.day, :sun | :mon) :: Types.weekday
def day_of_week(year, month, day, weekstart) when is_date(year, month, day) and weekstart in [:sun, :mon] do
cardinal = mod((trunc(julian_date(year, month, day)) + 1), 7)
case weekstart do
:sun -> cardinal
:mon -> mod(cardinal + 6, 7) + 1
end
end
def day_of_week(_, _, _, weekstart) when not weekstart in [:sun, :mon] do
{:error, {:bad_weekstart_value, expected: [:sun, :mon], got: weekstart}}
end
def day_of_week(_,_,_, _) do
{:error, :invalid_date}
end
defp mod(a, b), do: rem(rem(a, b) + b, b)
end