How can I convert seconds to time in Scala? - scala

println("What is the current number of seconds since midnight?")
val s = readInt
val m = (s/60) % 60
val h = (s/60/60) % 24
That is my current code. I just do not know how to println("") so it displays in hh:mm form. Thank you in advance for any help!

I think the answer is
"%02d:%02d".format(h, m)
based on http://www.scala-lang.org/old/node/5153

Mostly like #Floris said:
val s = System.currentTimeMillis / 1000
val m = (s/60) % 60
val h = (s/60/60) % 24
val str = "%02d:%02d".format(h, m)
// str = 22:40
Now you could print it, just like you would with regular string.
Since scala 2.10 there is string interpolation feature, which allows you to write things like:
val foo = "bar"
println(s"I'm $foo!")
// I'm bar!
But I don't think it is much readable (reminds perl):
val str = f"$h%02d:$m%02d"

// show elapsed time as hours:mins:seconds
val t1 = System.currentTimeMillis/1000
// ... run some code
val t2 = System.currentTimeMillis/1000
var elapsed_s = (t2 - t1)
// for testing invent some time: 4 hours: 20 minutes: 10 seconds
elapsed_s=4*60*60 + 20*60 + 10
val residual_s = elapsed_s % 60
val residual_m = (elapsed_s/60) % 60
val elapsed_h = (elapsed_s/60/60)
// display hours as absolute, minutes & seconds as residuals
println("Elapsed time: " + "%02d:%02d:%02d".format(elapsed_h, residual_m,
residual_s))

Related

Why do subsequent runs of scala function go orders of magnitude faster?

I'm having a very weird phenomenon occur. I'm hashing some mockup ssoids, and timing it since our application is timing critical. The first run of the function takes ~210 milliseconds, which is ridiculous and won't work. However, the 2nd, 3rd, and 4th runs take a few thousand nanoseconds each. I'm really confused, what's going on? Is there some caching I can do to make the first run just as fast?
See the code here:
object Main {
def main(args: Array[String]): Unit = {
val qq = "847bf1dc46ca22dc93259c5e857d6333"
val oo = "847bf1dc46ca22dc9eriuerie9duy45"
val xx = "909909ewufv9026854509erie9ifkf3"
val ww = "65984jg3oiqh4g3q383423932824344"
val qqq = getBytes(qq)
val ooo = getBytes(oo)
val xxx = getBytes(xx)
val www = getBytes(ww)
val t1 = System.nanoTime
val r1 = XxHash64.hashByteArray(qqq, seed = 0)
val duration = (System.nanoTime - t1)
val t2 = System.nanoTime
val r2 = XxHash64.hashByteArray(ooo, seed = 0)
val duration2 = (System.nanoTime - t2)
val t3 = System.nanoTime
val r3 = XxHash64.hashByteArray(xxx, seed = 0)
val duration3 = (System.nanoTime - t3)
val t4 = System.nanoTime
val r4 = XxHash64.hashByteArray(www, seed = 0)
val duration4 = (System.nanoTime - t4)
println(duration)
println(duration2)
println(duration3)
println(duration4)
println(r1)
println(r2)
println(r3)
println(r4)
}
(Also note I recognize this is a slipshod way of doing timings, but I've just started.)

Convert minutes to hours scala

I have a number in minutes, for example:
Int totalminutes= 342
I want to dispaly it like this:
5h:42m:..s
I did a scala function to convert the minute to hour and return HH:MM:SS
scala> def convertSeconds(input:Int):String ={
| val totalMinutes = input/60
| val seconds = input%60
| val minutes = totalMinutes%60
| val hours = totalMinutes%60
|
| return "%sh:%sm:%ss".format(hours,minutes,seconds)
| }
convertSeconds: (input: Int)String
I did my tests:
scala> convertSeconds(120) // 120 minutes
res22: String = 2h:2m:0s // why it add 2 minutes
scala> convertSeconds(60) // 60 minutes
res23: String = 1h:1m:0s // adding 1 minute
scala> convertSeconds(36) // 36 minutes
res24: String = 0h:0m:36s // I want to return 0h:30m:06s
The solution is:
scala> def convertSeconds(input:Int):String ={
//val totalMinutes = input/60
//val seconds = input/60%60
val minutes = input%60
val hours = input/60
return "%sh:%sm".format(hours,minutes)
}
convertSeconds: (input: Int)String
scala> convertSeconds(36)
res57: String = 0h:36m
scala> convertSeconds(120)
res58: String = 2h:0m
scala> convertSeconds(122)
res59: String = 2h:2m
scala> convertSeconds(2166)
res60: String = 36h:6m
Your function is supposed to be like this and you pass seconds not minutes:
def convertSeconds(input:Int):String ={
val hours = input/3600
val minutes = (input-hours*3600)/60
val seconds = input%3600-minutes*60
"%sh:%sm:%ss".format(hours,minutes,seconds)
}
If you want to pass minutes, the function should be something like this, I named it convertMinutes, and your seconds will zero, and you can get in your prescribed display by this code:
def convertMinutes(input:Int):String ={
val hours = input/60
val minutes = input-hours*60
"%sh:%sm:%ss".format(hours,minutes,"..")
}
In Scala REPL:
scala> convertSeconds(7523)
res4: String = 2h:5m:23s
scala> convertSeconds(9523)
res5: String = 2h:38m:43s
scala> convertSeconds(3724)
res6: String = 1h:2m:4s
scala> convertMinutes(342)
res10: String = 5h:42m:..s
I am not sure if you need a separate function to achieve this.
Scala already gives a library to do that
scala> val secs = 62
secs: Int = 62
scala> import scala.concurrent.duration._
scala> val inTime = Duration(secs,SECONDS)
inTime: scala.concurrent.duration.FiniteDuration = 62 seconds
scala> "%02d:%02d:%02d".format(inTime.toHours,inTime.toMinutes%60,inTime.toSeconds%60)
res8: String = 00:01:02
EDIT-1: What this does not handle is if you pass a number >= 86400 (total seconds in a day)
In Java, trusting you to translate yourself:
int totalminutes = 342;
Duration dur = Duration.ofMinutes(totalminutes);
String display = String.format("%dh:%02dm:%02ds",
dur.toHours(), dur.toMinutesPart(), dur.toSecondsPart());
System.out.println(display);
This prints:
5h:42m:00s
If had a number of seconds instead, use Duration.ofSeconds instead.
Don’t do the calculation yourself. It’s error-prone and it will require your reader to take some time to convince herself/himself that your calculation is correct. Instead let the library methods do the calculations, even when they seem trivial.
What went wrong in your code?
It’s been said already: You used
val hours = totalMinutes%60
This should have been a division:
val hours = totalMinutes / 60
It’s easier than you might expect to make such an error. For comparison you don’t that easily call toMinutesPart when you intended toHours, and if you still do, it’s easier to spot the bug.

How to properly measure elapsed time in Spark?

I have my code written in Spark and Scala. Now I need to measure elapsed time of particular functions of the code.
Should I use spark.time like this? But then how can I properly assign the value of df?
val df = spark.time(myObject.retrieveData(spark, indices))
Or should I do it in this way?
def time[R](block: => R): R = {
val t0 = System.nanoTime()
val result = block // call-by-name
val t1 = System.nanoTime()
println("Elapsed time: " + (t1 - t0) + "ns")
result
}
val df = time{myObject.retrieveData(spark, indices)}
Update:
As recommended in comments, I run df.rdd.count inside myObject.retrieveData in order to materialise the DataFrame.

How do I write a script in Scala that converts the current time to the number of seconds since midnight?

I'm new to all of this; I'm currently taking CSC 101 and learning how to use Scala. This is our first assignment, and I don't know where to start. I was wondering if you could explain what each variable means and what it stands for?
I've been seeing the code below a lot, and I don't know what the percent signs mean or what they do.
val s = System.currentTimeMillis / 1000
val m = (s/60) % 60
val h = (s/60/60) % 24
Unfortunately it is not very straightforward. Here is some code for you:
import java.text.SimpleDateFormat
import java.util.Calendar
val formatter = new SimpleDateFormat("yyyy/MM/dd")
val cal = Calendar.getInstance()
val now = cal.getTime()
val thisDay = formatter.format(now)
val midnight = formatter.parse(thisDay)
// milliseconds since midnight
val msSinceMidnight = now.getTime - midnight.getTime
val secSinceMidnight = msSinceMidnight / 1000
println(secSinceMidnight)
You have to use Java APIs as shown above, or you could choose to use JodaTime library: http://www.joda.org/joda-time/.

Get the difference between two dates in hours

I'm trying to calculate the hour difference between two joda dates.
val d1 = getDateTime1()
val d2 = getDateTime2()
Here is what I did:
# attemp1
val hours = Hours.hoursBetween(d1, d2) // error - types mismatch
# attempt2
val p = Period(d1, d2, PeriodType.hours()) // error - there is such a constructor
p.getHours
So how do I do this?
The type of getDateTime1 should be org.joda.time.DateTime.
This woks fine:
val d1: org.joda.time.DateTime = DateTime.now
val d2: org.joda.time.DateTime = DateTime.nextMonth
val hours = Hours.hoursBetween(d1, d2)
// org.joda.time.Hours = PT672H
There is no factory method apply for Period, you should use new to create Period:
val p = new Period(d1, d2, PeriodType.hours())
// org.joda.time.Period = PT672H
If you are using nscala-time you could also use method to to get Interval and than convert it to Period:
d1 to d2 toPeriod PeriodType.hours
// org.joda.time.Period = PT672H
(d1 to d2).duration.getStandardHours
// Long = 672
Also try sbt clean.