Java how to remove last numbers of a long? - java

i'm working with a query to bring data acording to a given time. so i want to grab a timestamp an remove the last 3 digits of it. Is it possible? how? give me a hint i will totally apreciate that

If you want to REMOVE the digits, divide by 10^n:
long x = 1234567890L;
long removeLastNDigits(long x, long n) {
return x / Math.pow(10, n);
}
removeLastNDigits(x, 3) == 1234567L;
As pointed out by dasblinkenlight, if you want to 0 the last n digits then after removing them you need to add them back as 0:
long x = 1234567890L;
long zeroLastNDigits(long x, long n) {
long tenToTheN = Math.pow(10, n);
return (x / tenToTheN) * tenToTheN;
}
zeroLastNDigits(x, 3) == 1234567000L;

If you want to remove the last 3 digits, just divide by 1000 :
long l = ...;
l = l / 1000;
If you want to change the last 3 digits to 0, divide by 1000 and then multiple by 1000 :
long l = ...;
l = (l / 1000) * 1000;

just divide by 1000.
long x = 123456789L;
long withoutLast3 = x / 1000; // equals to 123456L

I think you should format your timestamp value according to the required format in the database, if that is what you are looking for that is fetching data based on date in a certain format.
You can format your date according based on a dateformatter and then use it in query.
Check
DateFormat
SimpleDateFormat

Related

Difference in time between strings

I was working on a coding challenge where the goal was to find the smallest time difference in a list of Strings. I gave up and looked at a solution which in all makes sense, but I'm confused on the method parseTime. Can anybody please explain this method?
As I see it, the two hours compared are subtracted and then multiplied by 60 (becuase 60 min in one hour?).
From that the minutes are compared and then I get lost.. Can anybody explain this as simple as possible?
public static void main(String[] args) {
String[] strings = {"10:00am", "11:45pm", "5:00am", "12:01am"};
int i = TimeDifference(strings);
System.out.println(i);
}
public static int TimeDifference(String[] strArr) {
int min = Integer.MAX_VALUE;
for (int i=0; i<strArr.length; i++) {
for (int j=0; j<strArr.length; j++) {
if (i != j) {
int time = parseTime(strArr[j], strArr[i]);
if (time < min) min = time;
}
}
}
return min;
}
private static int parseTime(String time1, String time2) {
int time = (parseHour(time2) - parseHour(time1))*60;
time += parseMin(time2) - parseMin(time1);
if (isMorning(time2) != isMorning(time1)) {
time += 12 *60;
} else if (time <= 0 ) {
time += 24 * 60;
}
return time;
}
private static int parseHour(String time) {
int hour = Integer.valueOf(time.split(":")[0]);
return ( hour == 12? 0: hour);
}
private static int parseMin(String time) {
return Integer.valueOf(time.split(":")[1].replaceAll("[^0-9]",""));
}
private static boolean isMorning(String time) {
String post = time.split(":")[1].replaceAll("[^a-z]","");
return post.toLowerCase().equals("am");
}
Try to debug your code in your mind. Please check my comments below:
int minutes = parseTime("10:00am", "11:45pm");
private static int parseTime(String time1, String time2) {
int minutes = (parseHour(time2) - parseHour(time1))*60;//(11 - 10) * 60 = 60 minutes
minutes += parseMin(time2) - parseMin(time1); //60 + 45 - 0 = 105 minutes
if (isMorning(time2) != isMorning(time1)) { // 10:00am is not morning but 11:45pm is morning
minutes += 12 *60; //so we have to add 12 hours(12 * 60 minutes)
} else if (minutes <= 0 ) {
minutes += 24 * 60;
}
return minutes;
}
This is about regular expressions (RegEx). Let's look at 11:45pm as an example, and break up parseTime:
int time = (parseHour(time2) - parseHour(time1))*60;
The first line makes use of parseHour, which makes use of split, which splits the string around matches of the given regular expression, ":", and then parses the string at index 0 as an integer.
The string "11:45pm" is split into a string array {"11", "45pm"}, and the integer 11 is returned.
time += parseMin(time2) - parseMin(time1);
The second line makes use of parseMin, which similarly splits the given string, but parses the string at index 1 instead. However, the string "45pm" cannot be parsed as an integer, because it contains the non-digits "pm", so we use replaceAll to replace any non-digits with empty strings.
replaceAll replaces each substring of this string that matches the given regular expression with the given replacement.
"[^0-9]" matches any single character not present in 0-9, which is all nondigits, so "45pm".replaceAll("[^0-9]", "") returns "45", which is then parsed as an integer.
The rest has been answered by others already.
Yes, the difference in hours are converted to minutes by multiplying by 60. Then using parseMin the difference in minutes are added to it.
Now we need it check if it is AM or PM. Example : if the times were 10:30 am and 1:35 pm. The actual time difference is +115 minutes.
After parseHour the time would have a value of -600 ((1-10)*60). Then after parseMin, time would be -595 (difference of 5 minutes added). Now we need to see if it is AM or PM. Since time1 is AM and time2 is PM, we add a difference of 12hrs. This is because the same time in AM and PM would differ by 12hrs.
After this the time would be (-605 + 720) = 115 minutes.
The case when time<=0. This is when time2 is before time1. example time1 be 10:35am and time2 be 10:30am. So the question is - how much time would it take to REACH 10:30am FROM 10:35am. Since it is alreaddy 10:35am and since we cannot go back in time, we need to wait till the next day(24 hrs) to reach 10:30am. So we add 24*60 minutes to the time, which would give -5 + (24*60)

Get first N digits of a number

I'm writing a small program that displays the factorial of a number.
When I enter the number 20 I got the number 2432902008176640000 as result.
How can I limit a decimal number in Java.
For example the number 2432902008176640000 should be 2432 (limit 4).
Thanks in advance.
The following might do what you want, if what you want to do is what I think you want to do:
long n = 2432902008176640000L; // original number
while (n > 9999) {
// while "more than 4 digits", "throw out last digit"
n = n / 10;
}
// now, n = 2432
And a demo.
Notes:
A long can only represent values as large as 9223372036854775807 (which is only about 4 times as large as the number given) before it will overflow. If dealing with larger numbers you'll need to switch to BigInteger or similar. The same technique can be used, updated for syntax differences.
As fge pointed out, this won't work as it is written over negative numbers; this can be addressed by either changing the condition (i.e. n < -9999) or first obtaining the absolute value of n (and then reverting the operation at the end).
As done in yinqiwen's answer, n > 9999 can be replaced with n >= (long)Math.pow(10, N) (preferably using a temporary variable), where N represents the number of decimal digits.
Replace N by the limit.
long v = 2432902008176640000L;
long x = (long) Math.pow(10, N);
while(v >= x)
{
v /= 10;
}
Try this, may help:
Long n = 2432902008176640000;
String num = String.valueOf(n);
num = num.subString(0, 4);
n = Long.valueOf(num);
I am assuming you mean factorial of a number.
Just convert the number into a string and use substring method to get first 4 digits only.
fact is the factorial value
String result_4_str=(fact+"").substring(0, 4);
long result_4 = Long.parseLong(result_4_str);
System.out.println(result_4);
Some of the previous answers with loops are O(n) time complexity. Here's a solution for constant time complexity:
long num = 2432902008176640000L;
int n = 4;
long first_n = (long) (num / Math.pow(10, Math.floor(Math.log10(num)) - n + 1));
You can try
long number = 2432902008176640000L ;
String numberStr = String.valueOf(number);
if(numberStr.length()>=4){
System.out.println(numberStr.substring(0, 4));
}

Find average of time in (hh mm ss) format in java

I want to Calculate the average of three time in hh:mm:ss format . I tried the following code .
public String calculateAverageOfTime()
{
String timeInHHmmss = "08:00:00 08:00:00 08:00:00";
String[] split = timeInHHmmss.split(" ");
long hh = 0,mm = 0,ss = 0;
for (int i = 0; i < split.length; i++)
{
String[] split1 = split[i].split(":");
hh += Long.valueOf(split1[0].trim());
mm += Long.valueOf(split1[1].trim());
ss += Long.valueOf(split1[2].trim());
}
hh = hh / split.length ;
mm = mm / split.length ;
ss = ss / split.length ;
String hms = String.format("%02d:%02d:%02d", hh,mm,ss);
return hms;
}
This code works well. Is there any efficient way to do this ? . Any method available in Java API .
Your current code is not correct, try for example with input 08:00:00 08:00:00 09:30:00. As #StephenC said it, you cannot average times by averaging hour, minute, second components. Times are like base-60 numbers, you know, 60 seconds + 1 = 1:00 instead of 61.
This is correct, calculating the sum of seconds, then taking average and converting back to time:
public static String calculateAverageOfTime(String timeInHHmmss) {
String[] split = timeInHHmmss.split(" ");
long seconds = 0;
for (String timestr : split) {
String[] hhmmss = timestr.split(":");
seconds += Integer.valueOf(hhmmss[0]) * 60 * 60;
seconds += Integer.valueOf(hhmmss[1]) * 60;
seconds += Integer.valueOf(hhmmss[2]);
}
seconds /= split.length;
long hh = seconds / 60 / 60;
long mm = (seconds / 60) % 60;
long ss = seconds % 60;
return String.format("%02d:%02d:%02d", hh,mm,ss);
}
Using Date, SimpleDateFormat or Joda would make the code easier to understand, but I don't think it can be more efficient than this, as this code does strictly what you want to do, which is averaging a base-60 number.
As others have pointed out, beware of the precision loss when averaging.
You might also want to validate that the input string is in the correct format, otherwise the algorithm will break.
There is no single method in the Java API that will solve this problem. But there are some that will help.
What you need to do is to break the problem down into parts:
Convert time strings to numbers.
Average the numbers
Convert the average back to a time string.
The problems of converting a time string to a number and a number to a time string can be solved using the SimpleDateFormat class, or the 3rd-party Joda time class library. Or you could manually extract the hours/minutes/seconds component, convert each to an integer and then compute the number of seconds.
The problem of averaging 3 numbers can be solved with one line of Java ... though you need to beware of the fact that integer division truncates the result.
For the record, you cannot average 3 times by averaging their three components, as you current code tries to do. It doesn't make mathematical sense.
Something like this should work:
String timeInHHmmss = "08:00:00 08:00:00 08:00:00";
String[] split = timeInHHmmss.split(" ");
long sum = 0L;
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
for (int i = 0; i < split.length; i++)
{
sum += sdf.parse(split[i]).getTime();
}
Date avgDate = new Date((sum/split.length));
System.out.println("avg Date is:"+sdf.format(avgDate));
Convert to java.util.Date and then you can do all kinds of operations.
Check Simple Date Format and Date

Convert simple time format to Special time format (hhmmt)

I'm trying to convert the time format (hh:mm:ss) to this Special Time Format (hhmmt)?
The Special Time Format (STF) is a 5 digit integer value with the format [hhmmt] where hh are the hours, mm are the minutes and t is the tenth of a minute.
For example, 04:41:05 would convert to 4411.
I'm not sure how to convert the seconds value (05) to a tenth of a minute (1).
Edit:
I've incorporated Adithya's suggestion below to convert seconds to a tenth of a minute, but I'm still stuck.
Here is my current code:
String[] timeInt = time.split(":");
String hours = timeInt[0];
String minutes = timeInt[1];
double seconds = Double.parseDouble(timeInt[2]);
int t = (int) Math.round(seconds/6);
if (t>=10) {
int min = Integer.parseInt(minutes);
// min+=1;
t = 0;
}
String stf="";
stf += hours;
stf += minutes;
stf += String.valueOf(t);
int stf2 = Integer.parseInt(stf);
return stf2;
I'm using a String to store the minutes value but it makes it difficult to increment it since it is a String and not a Integer. But when calculating the "t" (tenth of minute) I have to add 1 to minutes if it exceeds 10. If I were to use parseInt again it will exclude the 0 in front of minutes again.
How can I retain the leading zero and still increment the minutes?
Thanks.
I am guessing, its the value of seconds, compared to the tenth of a minute, which is 6 seconds. So formula for t would be
t= seconds/6 //rounded off to nearest integer
This makes sense as this value is always between 0 and 9, as seconds range from 0 and 59, so its always a single digit
For your example
t = 5/6 = 0.833 = rounded off to 1
Note the 6.0f in the division - this helps you avoid the INT truncation.
string FormatSpecialTime(string time)
{
if (time.Length != 8) throw YourException();
int HH, mm, SS, t;
if (!int.TryParse(time.Substring(0, 2), out HH)) HH = 0;
if (!int.TryParse(time.Substring(0, 2), out mm)) mm = 0;
if (!int.TryParse(time.Substring(0, 2), out SS)) SS = 0;
t = (int) Math.Round(SS / 6.0f);
if (t >= 10)
{
mm++;
t = 0;
}
if (mm >= 60)
{
HH += mm / 60;
mm = mm % 60;
}
return HH.ToString() + (mm > 10 ? mm.ToString() : #"0" + mm) + t;
}

Sum of the bits in Java

sorry Friends i did a mistake. I have did this mistake again. am really very sorry.
this is the Issue.
I have a time range like
int Starttime = 2 which mean(02:00)
int enttime = 8 which mean(08:00)
i want time in sum of bits,
example
00:00 1
01:00 2
02:00 4 -----
03:00 8 R
04:00 16 a
05:00 32 n
06:00 64 g
07:00 128 e
08:00 256 -----
and soo on till 23:00
so i need totalRange = 256+128+64+32+16+8+4 ;
it should be like this
sorry again.
Thanks
The table indicates that you want to map the hour value of a time to an integer value using this function:
int value = (int) Math.pow(2, hourValue);
or, in other words, 00:00h will map to 20, 12:00h to 212 and so on.
Now if you have need the sum of start and endtime, you can simple use the function from above and add the values:
int totalrange = (int) Math.pow(2, starttime) + (int) Math.pow(2, endtime);
Now if you have starttime=2 and endtime=23, this will give a result (written in binary):
01000000 00000000 00000100
shamelessly adapting polygenelubricants much faster solution:
int totalrange = (1 << starttime) + (1 << endtime);
This works, because 2i is equal to (1 << i).
System.out.println(Integer.toBinaryString(2+24)); // 11010
This uses the Integer.toBinaryString method. There's also toHexString, toOctalString, and a toString with variable radix.
If you need the string to be zero-padded to a specific width, you can write something simple like this:
static String binaryPadded(int n, int width) {
String s = Integer.toBinaryString(n);
return "00000000000000000000000000000000"
.substring(0, width - s.length()) + s;
}
//...
System.out.println(binaryPadded(2+24, 8)); // 00011010
There are different ways to zero pad a string to a fixed width, but this will work for any int value.
For hexadecimal or octal, you can use formatting string instead:
System.out.println(String.format("%04X", 255)); // 00FF
The specification isn't very clear, but it looks like you want this mapping:
0 -> 1
1 -> 2
2 -> 4
3 -> 8
4 -> 16
:
i -> 2i
In that case, your mapping is from i to (1 << i) (the << is the bitwise left-shift operator).
System.out.println(
(1 << 2) + (1 << 4)
); // 20
Note that depending on what is it that you're trying to do, you may also consider using a java.util.BitSet instead.
BitSet demonstration
This may be completely off-the-mark, but assuming that you're doing some sort of interval arithmetics, then BitSet may be the data structure for you (see also on ideone.com):
import java.util.BitSet;
//...
static String interval(BitSet bs) {
int i = bs.nextSetBit(0);
int j = bs.nextClearBit(i);
return String.format("%02d:00-%02d:00", i, j);
}
public static void main(String[] args) {
BitSet workTime = new BitSet();
workTime.set(9, 17);
System.out.println(interval(workTime));
// 09:00-17:00
BitSet stackOverflowTime = new BitSet();
stackOverflowTime.set(10, 20);
System.out.println(interval(stackOverflowTime));
// 10:00-20:00
BitSet busyTime = new BitSet();
busyTime.or(workTime);
busyTime.or(stackOverflowTime);
System.out.println(interval(busyTime));
// 09:00-20:00
}
Note that methods like nextSetBit and nextClearBit makes it easy to find empty/occupied time slots. You can also do intersect, or, and, etc.
This simple example only finds the first interval, but you can make this more sophisticated and do various arithmetics on non-contiguous time intervals.
Integer.toBinaryString(i)
Returns a string representation of the integer argument as anunsigned integer in base 2.
To compute the length of the time-interval, you have to do
int totalrange = endtime - starttime;
Perhaps this is what you're looking for:
int startTime = 2;
int endTime = 24;
int range = endTime - startTime;
System.out.println(range + " can be expressed as the following sum:");
for (int size = 1; range > 0; size <<= 1, range >>= 1)
if ((range & 1) != 0)
System.out.format("+ %02d:00%n", size);
Output:
22 can be expressed as the following sum:
+ 02:00
+ 04:00
+ 16:00

Categories

Resources