# How To Convert Date To Unix Timestamp Without Using A Built In Function – R

For this tutorial, I will talk about how to convert a date string into a Unix Timestamp format. A Unix Timestamp is a time record of a particular time instance of how far that instance in milliseconds is away from the 0:0:0 of January 1st, 1970 in GMT+0 timezone. A positive timestamp is how far the time instance is after the 0:0:0 of January 1st time instance, 1970. A negative timestamp is how far the time instance is before the 0:0:0 of January 1st, 1970 time instance.

A Unix Timestamp consists of a whole number which represents seconds and three digits behind the decimal of which represents milliseconds. Most of us do not include millisecond into timestamp calculation. Thus the digits behind the decimal in a timestamp are usually removed. For the purpose of this demonstration, I will only use seconds and not milliseconds. For simplicity, we are going to only calculate the day as if we are at the 0:0:0 instance of that day.

For every type of programming language, there will most likely be a function that will convert a timestamp to date format or vice versa that built into the programming language. However, sometimes they are limited in function. In other events, we can encounter situations where we are working inside a very strict programming environment that do not give us the ability to import an external library. That event, in fact, did happen to me. This is why I wrote my own timestamp converter.

From that event, I learn one thing for certain. As programming language innovate to become better and better, sometimes we rely mostly on external library codes. Those additional libraries that we use in our program can help us efficient our programming process. However, sometimes it can make us become a little bit lazy to try to understanding the basic structure of how to solve our problems in principle. In my opinion, yes I do rely on the additional library when I program but when I have the time to learn, I will try to learn how that library solved my problem. Sometimes it sharpens my skill and knowledge.

The procedures for converting a timestamp without aid from another function can be a challenge. This is due to the fact that you have to keep track of leap year, century leap and quad century leap year. Keeping track of the leap counts is not the only challenge we have. We also have to know that they only occur after or before February the 29 depends on which direction we are to 1970.

This tutorial will only discuss in regard to converting date as in the zero hours of the day. For converting timestamp with hours, minutes and seconds. We first convert the date to a timestamp. If the time instance is after 1970, we can use this formula for calculating time: seconds + (minutes* 60) + (hours * 60 * 60). After that, we would add the previous time value to our timestamp. If the time instance is before 1970, we would still calculate the timestamp for the date first. After that, we would use this formula for calculating the hours, minutes and seconds time of the date: 86400 – ( seconds + (minutes* 60) + (hours * 60 * 60) ). Then we would take our timestamp value and minus off the previous equation result.

In the future, I might incorporate the explanations into this article and remove the comments from the source code. Therefore this article and its source code may change.

For a R’s built-in function that will convert a date to a timestamp. The code lines below can be utilized.

```a <- as.numeric(as.POSIXct("2013-09-06", format="%Y-%m-%d"))
```

### Start Of Tutorial Script

```# dateToTimeStamp function work on yyyy-mm-dd
# This function feature is to convert a date string in the format of yyyy-mm-dd or yyyy/mm/dd to a Unix timestamp.
# There are other versions of this timestamp converter available on my website.
# Without this function you can use the R's built-in function.
# This function will work from the year 50 to 5500 due to how much a 64 bits long integer can hold.
# R built in library code: R function doesn't have any flaw in its design and can convert really far in the future or really far in the pass
#                          a <- as.numeric(as.POSIXct("2013-09-06", format="%Y-%m-%d"))

dateToTimeStamp <- function(value){
# This is the output value.
out <- 0
# Vector for splitting input.
datearray <- c()

# Without an input value, the script will end.
if ( exists('value') == FALSE || nchar(value) < 1 ){
stop("There is not an input value")
# First, check for the format of yyyy-mm-dd
} else if ( grepl("^\\d{4}-{1}\\d{1,2}-{1}\\d{1,2}\$", value, perl = TRUE ) ) {
# Split the digits into chunks and store into an array.
datearray = strsplit(value, "-")[[1]]
# Second, evaluate date in the format of yyyy/mm/dd
} else if ( grepl("^\\d{4}\\/{1}\\d{1,2}\\/{1}\\d{1,2}\$", value, perl = TRUE )){
datearray = strsplit(value, "/")[[1]]
# If the input value does not match the previous date format, the program will exit with an error.
} else {
stop("Incorrect format")
}

# Convert the date values that stored inside the datearray into an integer value that corresponding to year, month and date.
inyyyy <- strtoi(datearray[1:1], 10)
inmm   <- strtoi(datearray[2:2], 10)
indd   <- strtoi(datearray[3:3], 10)

# Evaluate if the year is a leap year.
isLeap <- ifelse( ((inyyyy %% 4) == 0), 1 , 0)
# Evaluate if the year is a century leap year.
isCenturyLeap <-  ifelse(((inyyyy %% 100) == 0), 1 , 0)
# Evaluate if the year is a quad century leap year.
isQuadCenturyLeap <-  ifelse( ((inyyyy %% 400 ) == 0) , 1 , 0)

# Year, date or month's values can't be less than one.
if ( inmm < 1 || indd < 1 || inyyyy < 1){
stop("Month date and years input can't be less than 1")
# Date value can't be larger than 31.
} else if (indd > 31){
stop("Day cannot be great than 31.")
# Date value can't be larger than 29 if the month is February
} else if (inmm == 2 && indd > 29){
stop("February can't have more than 29 days")
# For the month of April, June, September and November, the date value can't be greater than 30.
} else if ( (inmm == 4 && indd > 30) || (inmm == 6 && indd > 30) || (inmm == 9 && indd > 30) || (inmm == 11 && indd > 30) ){
stop("April, June, September and November can't have more than 30 days")
# Month value can't be greater than 12.
} else if (inmm > 12){
stop("Month cannot be greater than 12.")
# The maximum support for this timestamp converter is a 64 bits long integer. Therefore, I safety net the below year to the year 50.
} else if (inyyyy < 50) {
stop("Memory doesn't allow us to convert year below 50")
# The maximum support for this timestamp converter is a 64 bits long integer. Therefore I safety net the above year to the year 5500.
} else if (inyyyy > 5500) {
stop("Memory doesn't allow us to convert year above 5500")
# If this is not a leap year then February can't have more than 28 days.
} else if (isLeap != 1 && inmm == 2 && indd > 28){
stop("This is not a leap year, you can't have 29 days in Feburary")
# If this is a century leap year but is not a quad centuary leap year then February can't have more than 28 days.
} else if (inmm == 2 && isCenturyLeap == 1 && isQuadCenturyLeap != 1 && indd > 28 ){
stop("This February can't have 29 days. Although it is a leap year, leap year is skipped on years that are divisible 100 years but will not skip if the year is divisible by 400")
}

# This vector store the amount days that each month have. We count february at 28 because we will modify our equation to match the leap year value.
dateinmonth <- c(31,28,31,30,31,30,31,31,30,31,30,31)
# Variable for storing how many leap days occur since input year to 1972 or to 1968
leapv <- 0
# Variable for storing the total date since input year to 1972 or 1968.
totaldate <- 0
# Variable for storing the year from.
yeardate <- 0
# Variable for storing how many days left in the current year of the input date.
dateleftinyear <- 0
# Variable for storing how days left in the current month of the input value.
dateleftinmonth <- 0

# What is a timestamp? A timestamp is a number string that contains a time value with the format of how many second since the 0:0:0 time of January 1, 1970.
# Timestamps are actually measured in milliseconds, However, for this tutorial, we only use the second for measurement.
# Negative timestamp is how far a time is below 1970. For instance, any date in 1969 and below will generate a negative timestamp.
# Positive timestamp is how far a time is above 1970. For instance, any date in 1970 and above will generate a positive timestamp. 1970 1 1 in this tutorial will generate a 0 timestamp.
# The first challenge we meet is the leap year.
# Timestamp takes into account leap years, century leaps and quad century leaps.
# What does leap years mean?
# We get the 29th day in February if the year is divisible by four. We don't get the 29th day if the year is divisible by 100 but is not divisible by 400.

# The method I prefer to use for calculating leap is if we are above 1970, we will use the closet below leap year. Which would be the year 1968 for calculating leap year value.
# This is the fact that we only need to round down our number after we subtract the year value to 1968 then divide by four.
# If we use 1970 every time we hit a decimal .5 or .75 we have to round up.

# My formula for calculating time values that are above the 0:0:0 time of January 1st, 1970 is as follow:
# Since we use leap to calculate to 1968, we will calculate to the 1st day of 1968 and then subtract off the result value a value of two 365 days years.
# y = (input year value - 1968) * 365
# d = date from the beginning of year = 365 - ((total date in input month - input date) + (How many day left in the year since one month after the input month).
# l = How many times leap year has occurred since 1968. Take input year - 1968 / 4. The whole number here is what we want not the decimal. If the value contained a decimal point, leap year had not happened yet for the decimal part of the value.
# c = How many times century leap has occurred since 1968. Input year - 1968 / 100. The whole number here is what we want and not the decimal.
# q = How many times quad century leap has occurred since 1968. Input year - 1968 / 400. The whole number here is what we want and not the decimal.
# totaldate = y - d + l - c + q ;
# timestamp = (totaldate * 86400) - 63158400   // 86400 is how many seconds that is in a day. and 63158400 is the amount of second that contains within two years that is 365 days each.
# Since we are calculating to 1968 we have to subtract the amount of second in two years from the result value.

# For the purpose of this tutorial I divide the code into what happen if the time value is above the 0:0:0 time of 1970 and what happen if it is below.
# It is possible to combine the equation and modify the equation as desired.

if (inyyyy >= 1970){
leapv <- floor(((inyyyy - 1968) / 4))
centuryleapv <- floor(((inyyyy - 2000) / 100))
quadcenturyleapv <- floor(((inyyyy - 2000) / 400))
length <- length(dateinmonth)
dateleftinmonth <- dateinmonth[inmm] - indd

# Get how many date left in a the year since after the input month.
if (inmm < 12){
for (i in (inmm+1):length) {
dateleftinyear = dateleftinyear + dateinmonth[i]
}
}

# Get how many days occurred since the begining of year to input date by subtracting 365 to (dateleftinmonth + dateleftinyear)
datefrombeginingofyear <- 365 - (dateleftinmonth + dateleftinyear)

# The real challenge we have for calculating leap is.
# On the year that it is a leap year, we do not have the extra day until we have passed the 29th of February.
# Hence, although in a leap year, if we have not passed the 29th day, we can't add leap values to our equation.
# However, the automatic formula has already taken into account the values for leap year.
# Therefore those values, have to be subtract off if we has not passed the 29 day of Feburary.
# Each if loop below is associate with a type of leap calculation.

if (isLeap == 1 && inmm < 3 ){
leapv <- ifelse(((inmm < 2) || (inmm == 2 && indd <= 29)), (leapv - 1), leapv)
}
if (isCenturyLeap == 1 && inmm < 3 ){
centuryleapv <- ifelse(((inmm < 2) || (inmm == 2 && indd <= 29)), (centuryleapv - 1), centuryleapv)
}
if (isQuadCenturyLeap == 1 && inmm < 3 ){
quadcenturyleapv <- ifelse(((inmm < 2) || (inmm == 2 && indd <= 29)), (quadcenturyleapv - 1), quadcenturyleapv)
}

# After evaluate and obtains all necessary value for the formula, we would calculate the result.
yeardate  <- (inyyyy - 1968) * 365
totaldate <- yeardate + datefrombeginingofyear + leapv - centuryleapv + quadcenturyleapv
out <- (totaldate * 86400) - 63158400

} else {

# My formula for calculating time values that are before the 0:0: time of January 1st, 1970 is as follow:
# The method I prefer to use for calculating leap values is, if we are below the year of 1970, we will use the closet above leap year, which would be the year 1972 for leap values calculation.
# Since we use the year 1972 for calculating leap values, we will calculate the second value to the 1st day of 1972, then we subtract two 365 days years from the equation.
# y = (input year value - 1972 + 1) * 365   # We will have a negative value of how far we are away from 1972, but we have to add one year here.
#                                            # This is because 1971 can be considered to be one year away from 1972.
#                                            # However it is not. We are still within the time frame of 365 days away but not really one year away from 1972.
# Because we are calculating how far we are below.
# We simply just calculating how many days left in the year since the input date value.
# The previous procedure will let us know how far we are away from the end of the year.
# d = day left in the month = total day in input month - input date.
# e = day left in the year = total day left in the year after the input month.
#
# We want all the number below to be positive now.
# l = How many times leap year has occurred since 1972. 1972 - input year / 4. The whole number here is what we want and not the decimal value. The decimal values are leap year that has not occurred.
# c = How many times century leap has occurred since 1972. 1972 - input year / 100. The whole number here is what we want and not the decimal value.
# q = How many times century leap occur since 1972. 1972 - input year / 400. The whole number here is what we want and not the decimal value.
# The number now are in positive so that mean the further negative the further it is away.
# totaldate = y - d - e - l + c - q;
# timestamp = (totaldate * 86400) + 63158400 - 172800;   # 86400 is how many seconds that is in a day. and 63158400 is the amount of second that contained within a time frame of two 365 days years.
#                                                        # Since we calculate to 1972 we have to give back this value.
#                                                        # We have to also subtract two days from the equation which would be 172800 seconds.
#                                                        # In this formula, if we are on the 31st day of December 1969 to 1970 1 1.
#                                                        # We will not have any day left in the month or any day left in the year.
#                                                        # Hence that is a 0 value, but in true reality, we are one day away if we are counting from the zero hour.
#                                                        # Thus we have to subtract one day from the equation.
#                                                        # The same principle would apply when we borrow the 2 years to 1972
leapv <- floor( ((1972 - inyyyy) / 4))
centuryleapv <- floor( ((2000 - inyyyy)  / 100))
quadcenturyleapv <- floor(((2000 - inyyyy) / 400))
length <- length(dateinmonth)

# There is a difference when we are evaluating leap calculation for a time value that is before the time 0:0:0 of January 1st, 1970.
# Leap values will not be added to the equation unless we have passed the first day of March.
if (isLeap == 1 && inmm > 2){
leapv <- ifelse(((inmm > 2) || (inmm == 3 && indd >= 1)), leapv - 1 , leapv)
}
if (isCenturyLeap == 1 && inmm > 1 ){
centuryleapv <- ifelse(((inmm > 2) || (inmm == 3 && indd >= 1)), centuryleapv - 1 , centuryleapv)
}
if (isQuadCenturyLeap == 1 && inmm > 1 ){
quadcenturyleapv <- ifelse(((inmm > 2) || (inmm == 3 && indd >= 1)) , quadcenturyleapv - 1 , quadcenturyleapv)
}

dateleftinmonth = dateinmonth[inmm] - indd

if (inmm < 12){
for (i in (inmm+1):length ){
dateleftinyear <- dateleftinyear + dateinmonth[i]
}
}

yeardate <- (inyyyy - 1972 + 1 ) * 365
totaldate <- yeardate - dateleftinmonth - dateleftinyear - leapv + centuryleapv - quadcenturyleapv
out <- (totaldate * 86400) + 63158400 - 172800
}
return(out)
}

# Remove below this line when use
a <- dateToTimeStamp("5000-9-30")
print(a)```

This post was written by Kevin and was first post @ http://kevinhng86.iblog.website.
Original Post Name: "How To Convert Date To Unix Timestamp Without Using A Built In Function – R".