Joda Time decimal conversion and rounding - time

Is there a way in Joda time where-in the difference between two days (Period)
can be rounded off (up or down) to nearest day.
E.g.: 7 days and 15 hrs should be rounded to 8 days while 7days and 8 hours should be rounded off to 7 days.
I tried looking into PeriodFormatterBuilder, however it has methods which returns hours but nothing to round off (like ceil or floor).

As far as I know, there is no method in Jodatime for your case.
I wrote something like this, I hope it helps you;
public static void main(String[] args) {
getDiffer(new DateTime().plusDays(2), new DateTime().plusDays(4).plusHours(13));
getDiffer(new DateTime().plusDays(2), new DateTime().plusDays(4).plusHours(8));
}
private static void getDiffer(DateTime date1, DateTime date2) {
Period p = new Period(date1, date2);
int days = p.getDays();
int hours = p.getHours();
if (hours < 12)
System.out.println("Days = " + days);
else
System.out.println("Days = " + (days + 1));
}
And the result is;
Days = 3
Days = 2

Related

Least number of days required to finish watching all movies given durations array if you can watch maximum 3.00 duration movie per day

Input: double array representing duration of movies e.g.
durations[] ={1.01, 2.4, 1.01, 1.01, 1.4}. You can watch maximum
3.00 duration movie per day.
Find the least number of days needed to finish watching all the movies.
Constraint: 1.01 <= duration[i]
<= 3.00.
(You can choose to watch any movie on a day and won't repeat
watching a movie)
Sample Test Cases:
Input: duration[] = {1.01, 2.4, 1.01, 1.01,
1.4} Output: 3
Input: duration[] = {1.01, 2.4, 1.4, 1.6, 2.6, 1.7} Output: 4
Input: duration[] = {1.01, 2.4, 1.5, 1.6, 2.6, 1.7} Output: 5
I got this in a placement coding test and couldn't finish it on time
but did it later using recursion. It worked with few test cases I
custom made but I'm not not sure if it will work for all possible
test cases. Also I feel it could be enhanced for better time
complexity. Kindly help.
My insight: You would be able to watch max 2 movies a day as
durations are always >= 1.01 so watching any 3 movies would make
duration exceed 3.00.
Here's my code:
import java.util.ArrayList;
public class MoviesBetterSolution {
public static void main(String[] args) {
double arr[] = {2.0,1.01,1.4,2.4,1.71}; //test case
System.out.println( f( 0, 0.00 , 1, 3.00, new ArrayList<Integer>(), arr , 0) );
//days passed a 1 as we start from day 1
//initial wtn (watched till now for a particular day) passes is 0.00
} static int minDays = Integer.MAX_VALUE;
//wtn -> watched till now (keeps track of duration of movies watched on the current day
//taken keeps track of number of movies watched on current day
// picked : watched movies on the day till now private static int f(int i, double wtn, int days, double limit, ArrayList<Integer>
picked, double[] arr, int taken) {
//updating minDays after reaching a point where all movies have been watched
if(picked.size()==arr.length) {
if( days<minDays ) minDays = days;
return minDays;
}
if(i == arr.length) { //finished traversing array
if(taken != 0) { //restart traversing to watch unwatched movies only if atleast 1
//movie was watched on the day, setting taken for the new traversal to be 0
i = 0;
taken = 0; }else { // otherwise just return if nothing was watched on the day, otherwise it
//will stackoverflow for all non watch choice recursion branch
return minDays;` } }
if((wtn + arr[i] <= limit) && !(picked.contains(i)) ) { //only movies that havent been watched can be watched
ArrayList<Integer> temp = new ArrayList<Integer>();
temp = (ArrayList<Integer>) picked.clone();
temp.add(i);
if(taken<2) { //as u can watch only 2 movies a day
f(i+1, wtn + arr[i] , days, limit, temp, arr, taken+1); //watch & move to next movie but on same day }
f(0, 0 , days +1 , limit, temp, arr, taken+1); // watch & move to next movie but on next day , wtn and index(i) set to 0 as u
starting new day }
f(i+1, wtn, days, limit, picked, arr, taken); //not watch & move to next movie on same day
return minDays; } }
Assuming all movies have run times between 1.01 and 3.00, solve this in O(n log n)
1. sort your list
2. set days = 0
3. set two pointers to the two ends of your list.
4. repeatedly do the following until all elements have been processed:
4.1 increment days
4.2 if the sum of the movies referred to is <= 3.0 then move both pointers towards the center, otherwise just decrement the larger one.
Just before the end, it's possible that both pointers refer to the same element. That takes a day.

BeanShell PreProcessor (JMeter) - How can I generate a random future DateTime Stamp that covers current time out to 7 days?

I need assistance. I got some of this code off another site. It was randomly generating a date for the previous 7 days and randomly generating an hour and minute within a 24 hour period (any). I need the opposite of sorts. I need a random time that covers the current "now" time and goes forward 7 days but also requires the time (hour and minute) to be within a set hour range.
Requirements
Random Date covering current day ("now") and ahead one week (7 days).
Random Time generated; however time must fall between the hours of 1000hrs to 2200hrs and formatted as ("yyyy-MM-dd'T'HH:mm:ss").
My BS PreProcessor Parameters I was passing for the below code are (1 5 5). My dates seem to generate just fine but my time is only generating random hours as hours within the next 5 hours. How can I set a time range of 10am-10pm?
import java.text.SimpleDateFormat;
import java.text.NumberFormat;
import java.util.Date;
import java.util.Random;
int minDay = Integer.parseInt(bsh.args[0]); // get first parameter minimal X Days ahead
int maxDay = Integer.parseInt(bsh.args[1]); // get second parameter maximal X Days ahead
int maxMinutesActivity = Integer.parseInt(bsh.args[2]); // get maximal duration of activity
int myThreadNum = 0;
int randomDay = 0; // RandomDays ahead
int minHour = 0;
int maxHour = 5;
int randomHour = 0;
int minMinute = 0;
int maxMinute = 60;
int randomMinute = 0;
int randomMinuteDuration = 0;
String formattedDate = "";
Random randomvar = new Random();
Date datevar = new Date();
Date datevarThisWeek = new Date();
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
NumberFormat myFormat = NumberFormat.getInstance();
myFormat.setMinimumIntegerDigits(2); // required to have minimal two digits for Day, Hour, Minute
myThreadNum = ${__threadNum}; // just to show the thread number in debug
vars.put("myThreadNum",myFormat.format(myThreadNum));
randomDay = minDay+randomvar.nextInt(maxDay-minDay+1); // randomDays ahead between minDay and maxDay
datevar.setDate(datevar.getDate() - randomDay );
vars.put("randomDay",myFormat.format(randomDay));
randomHour = 1+randomvar.nextInt(maxHour-minHour+1); // randomHour ahead between minHour and maxHour
vars.put("randomHour",myFormat.format(randomHour));
randomMinute = minMinute+randomvar.nextInt(maxMinute-minMinute+1); // randomHour ahead between minMinute and maxMinute
vars.put("randomMinute",myFormat.format(randomMinute));
randomMinuteDuration = maxMinutesActivity; // randomduration between 1 and maxMinutesActivity
vars.put("randomMinuteDuration",myFormat.format(randomMinuteDuration));
// Calculate a Start and End time for this Week
randomDay = 1+randomvar.nextInt(5-1+1); // randomDays ahead this Week
datevarThisWeek.setDate(datevarThisWeek.getDate() + randomDay );
datevarThisWeek.setTime(datevarThisWeek.getTime() + ((randomMinute + (randomHour * 60 )) * 60 * 1000 ));
//datevarThisWeek.setTime(datevarThisWeek.getTime() + ((randomMinute + (randomHour * 60 )) * 60 * 1000 ) + myThreadNum );
formattedDate = df.format(datevarThisWeek);
vars.put("randomFireTime_FUTURE",formattedDate);
datevarThisWeek.setTime(datevarThisWeek.getTime() + (randomMinuteDuration * 60 * 1000 ));
//datevarThisWeek.setTime(datevarThisWeek.getTime() + (randomMinuteDuration * 60 * 1000 ) + myThreadNum );
formattedDate = df.format(datevarThisWeek);
vars.put("randomOrderTime_FUTURE",formattedDate);
Java fake library Might helps you.
import com.github.javafaker.Faker;
Date dob= faker.date().between(date1,date2);

Determine day based on number

I just want to ask if how do you determine
Enter a number: 14
Then the date to day is Sunday.
the above demonstration is from 1-7=monday-sunday then if the value is 8 then its monday again...but how could I determine it?using loops and modulo?...
I appreciate any comments for helping me...
any language are ok, I just want to know the algorithm with it...
You can just use module
Module got to 0 so it would be something like
<?php
$value = 13;
$daynames = array("mon", "tues", "wed", "thur", "fri", "sat", "sun");
// The + 1 is because % is 0, and you want 1-7
echo (($value % 7) + 1) . "day of the week";
echo "the day is " . $daynames[($value % 7)];
?>
Example: http://codepad.org/wbGuMI06
If you have a switch/case or if/else for the seven days you can use modulo 7 to get the input into the desired range of 7 days.
You can use a switch statement and modulo arithmetic to do this.
The first step to learning computer science is to learn that numbers don't usually start at 1. They start at 0. Getting this idea down will help you tremendously in the future!
// accept numbers 0-6. If 7 were to get put in, it would end up being 0 since 7 % 7 = 0.
switch(num % 7) {
case 0: return "Sunday";
case 1: return "Monday";
case 2: return "Tuesday";
/// rest here...
default: throw new IllegalArgumentException();
}
Taking the number modulo 7 would seem like the obvious possibility.
In C++, int day = (i-1) % 7; will give you a zero-based offset. Here's sample code:
#include <iostream>
#include<string>
using namespace std;
int main()
{
static const std::string days [] =
{
"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday"
};
static const size_t num_days = sizeof(days)/sizeof(days[0]);
for( int i = 1; i <= 31; ++i )
{
int day = (i-1) % 7;
cout << day << " = " << days[day] << "\n";
}
}
Get modulo 7 of the int value thats passed in and make a switch statement for it.
switch:
case 1:
Sunday
case 2:
Monday
// and so on
string day;
int inputNumber;
if(inputNumber%7 == 0)
day = "monday"; // or sunday if you prefer :p
else if(inputNumber%7 == 1)
day = tuesday
...
...
...
datArr= new Array ('Sun', 'Mon', 'Tue',Wen', 'Thu, 'Fri', 'Sat');
day =datArr[(daynum%7)];
If Sunday gets treated as day zero there is no need to subtract 1 after the modulo. Of course most of the solutions will fail with zero dive if an actual value of zero is encountered.
import java.util.Scanner;
public class TestMain {
private static final String[] DAYS = new String[] { "Sunday", "Monday", "Tuesday", "Wednesday", "Thusday", "Friday", "Saturday" };
public static void main(final String[] args) {
System.out.print("Enter a number: ");
final Scanner scanner = new Scanner(System.in);
final int n = scanner.nextInt();
System.out.print("Then the date to day is " + DAYS[n % 7]);
}
}

Algorithm to determine if a given date/time is between two date/time pairs

I have an array of dates in a one week range stored in an unusual way.
The Dates are stored in this numeric format: 12150
From left to right:
1st digit represents day: 1 = sunday, 2 = monday, 3 = tuesday, ...., 7 = saturday
next two digits represent hour in a 24 hour system: 00 = midnight, 23 = 11pm
next two digits represent minutes: 00-59
Given an input date and a start date and end date I need to know if the input date is between the start and end date.
I have an algorithm right now that I think works 100% of the time, but I am not sure.
In any case, I think there is probably a better and simpler way to do this and I was wondering if anybody knew what that algorithm was.
If not it would be cool if someone could double check my work and verify that it does actually work for 100% of valid cases.
What I have right now is:
if (startDate < inputDate &&
endDate > inputDate) {
inRange = yes;
}
else if (endDate < startDate) {
if((inputDate + 72359) > startDate &&
(inputDate + 72359) < endDate) {
inRange = yes;
}
else if((inputDate + 72359) > startDate &&
(inputDate + 72359) < (endDate + 72359)) {
inRange = yes;
}
}
How about
const int MAX = 72460; // Or anything more than the highest legal value
inRange = (MAX + inputDate - startDate) % MAX <
(MAX + endDate - startDate) % MAX;
This assumes of course that all the dates are well formed (according to your specs).
This addresses the case where the start is "after" the end. (e.g. Friday is in range if start is Wednesday and end is Monday)
It may take a second to see (which probably isn't good, because readability is usually the most important) but I think it does work.
Here's the basic trick:
Legend:
0: Minimum time
M: Maximum time
S: Start time
1,2,3: Input Time test points
E: End Time
The S E => Not in range
2 In range
3 > E => Not in range
The S > E case
0 M
Original -1--E----2---S--3--
Add Max -------------------1--E----2---S--3--
Subtract StartDate ------1--E----2---S--3--
% Max S--3--1--E----2----
1 In range
2 > E => Not in range
3 In range
If you really want to go nuts (and be even more difficult to decipher)
const int MAX = 0x20000;
const int MASK = 0x1FFFF;
int maxMinusStart = MAX - startDate;
inRange = (maxMinusStart + inputDate) & MASK <
(maxMinusStart + endDate) & MASK;
which ought to be slightly faster (trading modulus for a bitwise and) which we can do since the value of MAX doesn't really matter (as long as it exceeds the maximum well-formed value) and we're free to choose one that makes our computations easy.
(And of course you can replace the < with a <= if that's what you really need)
There is some logic error with dates in that format. Since the month and year information is missing, you cannot know what calendar day is missing. e.g. 50755 might be Thursday March 12 2009, but it might just as well be exactly a week ago, or 18 weeks ahead. That for you could never be 100% sure if any date in that format is between any other 2 dates.
Here the condition of the inner if can never be true, since endDate < startDate:
if (endDate < startDate) {
if((inputDate + 72359) > startDate &&
(inputDate + 72359) < endDate) {
// never reached
inRange = yes;
}
The following if also can't be optimal, since the first part is always true and the second part is just identical to inputDate < endDate:
if((inputDate + 72359) > startDate &&
(inputDate + 72359) < (endDate + 72359))
I think you want something like this:
if (startDate < endDate)
inRange = (startDate < inputDate) && (inputDate < endDate);
else
inRange = (startDate < inputDate) || (inputDate < endDate);
you should use >= and <= if you really want it in range
say i pick this date 10000 or 72359, how you would handle this? it is in range or not?
also i didn't know value for startDate and endDate since you didn't initialize it, correct me if i were wrong, variable that didn't initialized will start with 0 or null or ''
so i assume the startDate = 10000 and endDate 72359
btw why you pick this kind of array (as int or string value?) why first value was day? not date example:
010000 -> date 1st of the month 00:00
312359 -> date 31th of the month 23:59
but it's up to you :D
so sorry if i were wrong i took algorithm class only on university and it was 5 years ago :D
A better approach might be to normalize your data converting all the day of the week values to be relative to the start date. Something like this:
const int dayScale = 10000; // scale factor for the day of the week
int NormalizeDate(int date, int startDay)
{
int day = (date / dayScale) - 1; // this would be a lot easier if Sunday was 0
int sday = startDay - 1;
if (day < sday)
day = (day + 7 - sday) % 7;
return ((day+1) * dayScale) + (date % dayScale);
}
int startDay = startDate / dayScale; // isolate the day of the week
int normalizedStartDate = NormalizeDate(startDate, startDay);
int normalizedEndDate = NormalizeDate(endDate, startDay);
int normalizedInputDate = NormalizeDate(inputDate, startDay);
inRange = normalizedInputDate >= normalizedStartDate &&
normalizedInputDate <= normalizedEndDate;
I am pretty sure this will work as written. In any case, the concept is cleaner that multiple comparisons.
The simplest solution i found is this:
said x your generic time and S, E the start and end time respectively (with 0 < S,E < T):
f(x) = [(x-S) * (x-E) * (E-S) < 0]
This function returns TRUE if x is in between the start and end time, and FALSE otherwise.
It will also take care of start time bigger than end time (i.e. you start working at 20:00 and finish at 04:00, 23:13 will return TRUE)
i must say, considering the multiplications, it could not be the most efficient in terms of speed, but it is definitely the most compact (and pretty IMHO)
EDIT:
i found a much more elegant and efficient solution:
f(x) = (x<S) XOR (x<E) XOR (E<S)
you can substitute XOR with the "different" operator ( != )
I explain it:
The first formula comes from the considering the relation inequality study:
if S < E:
...............S.....E..........
(x-S)----------+++++++++++++++++
(x-E)----------------+++++++++++
(E-S)+++++++++++++++++++++++++++
total++++++++++------+++++++++++
so, the total is negative if x is in between S and E
if S > E:
...............E.....S..........
(x-S)----------------+++++++++++
(x-E)----------+++++++++++++++++
(E-S)---------------------------
total----------++++++-----------
so, the total is negative if x is bigger than S or smaller than E
To reach the final equation, you decompose the first formula in 3 terms:
(x-S)<0 => x<S
(x-E)<0 => x<E
(E-S)<0 => E<S
the product of these terms is negative only if they are all negative (true, true, true) or only one is negative and the other are positive (true, false, false, but the order does not matter)
Therefore the problem can be solved via
f(x) = (x<S) != (x<E) != (E<S)
These solution can be applied to any similar problem with periodic system, such as checking if the angle x is inside the arc formed by the two angles S and E.
Just make sure that all the variable are between 0 and the period of your system (2PI for arcs in a circle, 24h for hours, 24*60*60 for the seconds count of a day.....and so on)

Other examples of magical calculations

I have seen this topic here about John Carmack's magical way to calculate square root, which refers to this article: http://www.codemaestro.com/reviews/9. This surprised me a lot, I just didn't ever realized that calculating sqrt could be so faster.
I was just wondering what other examples of "magic" exist out there that computer games use to run faster.
UPDATE:
John Carmack is not the author of the magic code. This article tells more. Thanks #moocha.
There is a book which gathers many of those 'magic tricks' and that may be interesting for you: The Hacker's Delight.
You have for example many tricks like bit twiddling hacks etc... (you have several square root algorithms for example that you can see on the google books version)
Not exactly a mathematical hack, but I like this one about Roman Numerals in Java6:
public class Example {
public static void main(String[] args) {
System.out.println(
MCMLXXVII + XXIV
);
}
}
will give you the expected result (1977 + 24 = 2001), because of a rewrite rule:
class Transform extends TreeTranslator, an internal class of the Java compiler.
Transform visits all statements in the source code, and replaces each variable whose name matches a Roman numeral with an int literal of the same numeric value.
public class Transform extends TreeTranslator {
#Override
public void visitIdent(JCIdent tree) {
String name = tree.getName().toString();
if (isRoman(name)) {
result = make.Literal(numberize(name));
result.pos = tree.pos;
} else {
super.visitIdent(tree);
}
}
}
I'm a big fan of Bresenham Line, but man the CORDIC rotator enabled all kinds of pixel chicanery for me when CPUs were slower.
Bit Twiddling Hacks has many cool tricks.
Although some of it is dated now, I was awed by some of the tricks in "The Zen of Code Optimization" by Michael Abrash. The implementation of the Game Of Life is mind-boggling.
I have always been impressed from two classic 'magic' algorithms that have to do with dates:
Zeller's congruence for computing the day of week of a given date
Gauss's algorithm to calculate the date of Easter
Some (untested) code follows:
import math
def dayOfWeek(dayOfMonth, month, year):
yearOfCentury = year%100
century = year // 100
h = int(dayOfMonth + math.floor(26.0*(month + 1)/10) + yearOfCentury \
+ math.floor(float(yearOfCentury)/4) + math.floor(float(century)/4) \
+ 5*century) % 7
return ['Saturday', 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'][h]
def easter(year):
a = year%19
b = year%4
c = year%7
k = int(math.floor(float(year)/100))
p = int(math.floor((13 + 8.0*k)/25))
q = int(math.floor(float(k)/4))
M = (15 - p + k - q)%30
N = (4 + k - q)%7
d = (19*a + M)%30
e = (2*b + 4*c + 6*d + N)%7
day1 = 22 + d + e
if day1 <= 31: return "March %d"%day1
day2 = d + e - 9
if day2 == 26: return "April 19"
if day2 == 25 and (11*M + 11)%30 < 19: return "April 18"
return "April %d"%day2
print dayOfWeek(2, 12, 2008) # 'Tuesday'
print easter(2008) # 'March 23'

Resources