How to calculate 'Duration' between two 'DateTimes' - scala

I have two DateTime objects:
import org.joda.time.{DateTime, Hours}
import scala.concurrent.duration._
val t1: DateTime = DateTime.now
val t2: DateTime = /* Some other time in the future */
I want to calculate the duration between the two:
val d: Duration = Duration(t2 - t1)
Obviously the code above does not work. I tried minus, but that requires a Duration, not a DateTime.
What is the easiest way to do this?

Joda-Time
Use org.joda.time.Duration constructor taking a pair of DateTime objects.
Duration d = new Duration( t1 , t2 ) ;
java.time
Use the static factory method on the java.time.Duration class.
Duration d = Duration.between( t1 , t2 ) ;

Agree with #stefanobaghino, try to use java.time which is available out of box since java 8. Regarding your case, check this:
Duration
public Duration(ReadableInstant start,
ReadableInstant end)
Creates a duration from the given interval endpoints.
Parameters:
start - interval start, null means now
end - interval end, null means now
Throws:
ArithmeticException - if the duration exceeds a 64 bit long
You was very close, hah

import scala.concurrent.duration._
val d = Duration(t2.getMillis - t1.getMillis, MILLISECONDS)

Related

Add days to a datetime and convert it to a date ? - Odoo V14

i want to add 30 days to a datetime field and make my date field take this value as default.
I tried this, but don't work :/
from odoo import models, fields, api
from datetime import datetime
from dateutil.relativedelta import relativedelta
class crm_lead(models.Model):
_inherit = 'crm.lead'
date_deadline = fields.Datetime(string='Fermeture prévue')
#api.onchange('create_date')
def _onchange_enddate(self):
if self.create_date:
date_end = ( datetime.strptime(self.create_date, '%Y-%m-%d') + relativedelta(days =+ 30).strftime('%Y-%m-%d') )
self.date_deadline = date_end.date()
Thanks by advance !
The create_date is a magic field set in _create method. To use the creation date as a default value for the date_deadline field, you can use the default attribute and use the Date.today function to get the creation date.
Example:
date_deadline = fields.Datetime(default=lambda record: fields.Date.today() + relativedelta(days=30))
Does this work?:
from odoo import models, fields, api
from datetime import datetime, date, timedelta
class crm_lead(models.Model):
_inherit = 'crm.lead'
date_deadline = fields.Datetime(string='Fermeture prévue')
#api.onchange('create_date')
def _onchange_enddate(self):
if self.create_date:
date_end = ( date.today() + timedelta(30))
date_deadline = date_end
It gives the current date + 30 days.
It does not strip the datetime variable, so you might want to do that after.

joda Datetime. How to SET timezone to the parsed DateTime?

I'm using Scala along with play framework. I want to parse the String with simple date and say it's in UTC. So if I have 2018-10-04 I want to get 2018-10-04T00:00:00.000Z
With this:
DateTime.parse("2018-10-04", DateTimeFormat.forPattern("yyyy-mm-dd")).withZone(DateTimeZone.UTC)
I keep getting 2018-10-03T22:00:00.000Z if I have +2 timezone. How to just say that it's already in UTC?
One way is to use LocalDatetime to initially ignore the timezone:
scala> LocalDateTime.parse("2018-10-04", DateTimeFormat.forPattern("yyyy-MM-dd"))
res11: org.joda.time.LocalDateTime = 2018-10-04T00:00:00.000
then you can use toDateTime to make this UTC:
scala> LocalDateTime.parse("2018-10-04", DateTimeFormat.forPattern("yyyy-MM-dd")).toDateTime(DateTimeZone.UTC)
res12: org.joda.time.DateTime = 2018-10-04T00:00:00.000Z
Also: You should use MM (month) rather than mm (minute).
First the imports.
import org.joda.time.{DateTime, DateTimeZone}
import org.joda.time.format.DateTimeFormat
Since the time part is fixed, we can use a constant suffix for the time part.
val timeString = "T00:00:00.000Z"
We use string-interpolation to append this to the incoming dates.
DateTime.parse(s"2018-10-04$timeString", DateTimeFormat.forPattern("yyyy-mm-dd'T'HH:mm:ss.SSSZ")).withZone(DateTimeZone.UTC)

Check if Day is Saturday or Sunday

I'm looking to do a difference between 2 date in scala. These 2 date are should not saturday not sunday.
I did a scala function to test if the day if Saturday or Sunday:
I edited my question, this is my code to test if a day is saturday or sunday.
I should use it using tow dates : start_date and finish_date, because after this operation I'll do the difference between these tow dates.
My function jourouvree took one parameter, not a dates.
How can I modify my code to pass the tow dates.
Check if Day is Saturday or Sunday:
import java.time.{LocalDate, DayOfWeek}
def isWeekend(day: LocalDate) =
day.getDayOfWeek == DayOfWeek.SATURDAY ||
day.getDayOfWeek == DayOfWeek.SUNDAY
Using Java 8 datetime api:
import java.time._
import java.time.format.DateTimeFormatter
val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
//Assume d2,d2 themselves are not weekend days
def jourOuvree(sd1:String, sd2:String): Unit = {
val d1 = LocalDateTime.parse(sd1, formatter)
val d2 = LocalDateTime.parse(sd2, formatter)
//return if d1 is not earlier than d2. TODO: handle what to be done
if(d2.isAfter(d1) == false) return
var (days, dayCtr) = (1, 1)
while(d1.plusDays(dayCtr).isBefore(d2)){
dayCtr+=1
val dow = d1.plusDays(dayCtr).getDayOfWeek()
if(!dow.equals(DayOfWeek.SATURDAY) && !dow.equals(DayOfWeek.SUNDAY))
days+=1
}
println(days)
}
Invoke as below:
jourOuvree("2011-03-31 07:55:00", "2011-04-06 15:41:00")
You get 5 printed.
NOTE: The code doesn't handle exceptions in parsing.
Also, there may be other requirement fine points, for which you are the best judge to make required changes.

Always get "1970" when extracting a year from timestamp

I have a timestamp like "1461819600". The I execute this code in a distributed environment as val campaign_startdate_year: String = Utils.getYear(campaign_startdate_timestamp).toString
The problem is that I always get the same year 1970. Which might be the reason of it?
import com.github.nscala_time.time.Imports._
def getYear(timestamp: Any): Int = {
var dt = 2017
if (!timestamp.toString.isEmpty)
{
dt = new DateTime(timestamp.toString.toLong).getYear // toLong should be multiplied by 1000 to get millisecond value
}
dt
}
The same issue occurs when I want to get a day of a month. I get 17 instead of 28.
def getDay(timestamp: Any): Int = {
var dt = 1
if (!timestamp.toString.isEmpty)
{
dt = new DateTime(timestamp.toString.toLong).getDayOfYear
}
dt
}
The timestamp you have is a number of seconds since 01-01-1970, 00:00:00 UTC.
Java (and Scala) usually use timestamps that are a number of milliseconds since 01-01-1970, 00:00:00 UTC.
In other words, you need to multiply the number with 1000.
The timestamp that you have seems to be in seconds since the epoch (i.e. a Unix timestamp). Java time utilities expect the timestamp to be in milliseconds.
Just multiply that value by 1000 and you should get the expected results.
You can rely on either on spark sql function which have some date utilities (get year/month/day, add day/month) or you can use JodaTime library to have more control over Date and DateTime, like in my answer here: How to replace in values in spark dataframes after recalculations?

Python dateutil, check which value is given

I am parsing an excel document and get date time values...
I am using dateutil to convert it to python datetime values...
For example if incoming value is '2012' i need a way to understand that only year is given
or if value is '13:05' only hour-minute is given.
from dateutil.parser import *
def convertToDatetime(inValue):
#if inValue is '2012' i need a way to understand only year is given. Can i do this while parse method is used?
rVal = parse( inValue )
return rVal
How can i accomplish this?
----- EDIT ----
I can ask the question in this way too:
If only the year is given dateutil completes the day and month with today's values... But i need null values for month and day if only year is given...
This feature is yet to be implemented in the dateutil module. You can modify this snippet as per your requirement though.
from dateutil import parser
from datetime import datetime
import warnings
def double_parse(dt_str):
dflt_1 = datetime(1, 1, 1)
dflt_2 = datetime(2, 2, 2)
dt1 = parser.parse(dt_str, default=dflt_1)
dt2 = parser.parse(dt_str, default=dflt_2)
if dt2.year != dt1.year:
warnings.warn('Year is missing!', RuntimeWarning)
return dt1.replace(year=datetime.now().year)
return dt1
if __name__ == "__main__":
print(double_parse('2017-04-05'))
# 2017-04-05 00:00:00
print(double_parse('03:45 EST'))
# stderr: RuntimeWarning: Year is missing!
# 2017-01-01 03:45:00-05:00