I'm using Xamarin forms in my android app I'm getting the datetime that I converted to
Egypt time but some devices read it nulls or countries I don't know the reason really but some others read it?
and that is my code
DateTime date = DateTime.Now;
var test = TimeZoneInfo.ConvertTime(date, TimeZoneInfo.FindSystemTimeZoneById("Africa/Cairo"));
It might help you
DateTime now = DateTime.UtcNow;
TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Africa/Cairo Standard Time");
TimeSpan utcOffset = timeZoneInfo.GetUtcOffset(now);
DateTime cairoTime = new DateTime(now.Ticks + utcOffset.Ticks, DateTimeKind.Local);
Related
I have an app on the PlayStore and I am building a feature where the user will not see ads more than a specific number in one day.
I am thinking about comparing the current date and time to the previously saved one but haven't find a proper way to do that.
How can I compare date and time to know if 24 hours have passed or not?
Some posts that I found but not helpful:
medium.com
stackoverflow
stackoverflow
tl;dr
[This Answer uses Java syntax. You’ll have to translate to Kotlin syntax.]
if
(
Duration // Represents elapsed time on the scale of hours-minutes-seconds.
.between( // Calculates elapsed time between two points in time.
Instant.parse( "2021-03-23T15:30:57.013678Z" ) , // Last moment when an ad was show.
Instant.now() // Current moment.
) // Returns a `Duration` object.
.toHours() // Extract total number of whole hours from the `Duration` object.
>= 24L // Test if equals-to or greater-than 24 hours.
)
{ show ad }
java.time
You asked:
… know if 24 hours have passed or not?
Use the modern java.time classes defined in JSR 310. The java.time classes are built into Android 26 and later. Most of the functionality is available in earlier Android using the latest tooling’s “API desugaring“.
Instant adShown = Instant.parse( "2021-03-23T15:30:57.013678Z" ) ;
Instant now = Instant.now() ;
Duration d = Duration.between( adShown , now ) ;
long hoursSinceAdShown = d.toHours() ;
if( hoursSinceAdShown >= 24L ) { … show ad }
Record your next ad-showing as text in standard ISO 8601 format.
String output = Instant.now().toString() ;
2021-03-23T15:30:57.013678Z
Your Question asked for two different things:
Once per day
Every 24 hours
The first involves a calendar, dates, and a time zone. The second does not. I showed you code for the second.
You can use a scheduled executor service to trigger from a background thread the next showing of an ad at a specific moment. Search Stack Overflow to learn more as this has been covered many times already.
Use this code to check the current date, Yesterday or Particulardate. Pass Epoch time to this method
// input format (we get a value as Epoch)
private val inputFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
private val outputFormat = SimpleDateFormat("MMM dd")
// have to pass the time value as Epoch time.
private fun calculateDateMonth(time: String): String {
var returnValue = ""
val dateTime = DateTime((time.toLong()) * 1000L)
val inputTime = inputFormat.parse(dateTime.toString())
val convertDateMonth = outputFormat.format(inputTime!!)
val timeInMilliseconds = outputFormat.parse(convertDateMonth)!!
val mTime: Calendar = Calendar.getInstance()
mTime.setTimeInMillis(timeInMilliseconds.time)
val now = Calendar.getInstance()
returnValue = when {
now[Calendar.DATE] == mTime[Calendar.DATE] // check isToday
now[Calendar.DATE] - mTime[Calendar.DATE] == 1 // check Yesterday
else -> convertDateMonth // Month and Date
}
return returnValue
}
I have an iteration that runs for a set number of times depending on another value which can vary which is why I'm using an iteration that iterates based on that value, inside that iteration I add 30 days to a date once each iteration and then add the results to a table.
PROBLEMS
I simply end up with the first instance of adding 30 days which is outside the iteration itself. This means that my values inside the iteration are not being stored properly but I can't see why.
I've checked the DateTime operations and displayed the value of newdate and it shows the proper date so it's most likely the storing of the date. But I don't know what's going wrong, it works pre-iteration which is what's got me confused. Why isn't it executing inside the iteration? Does anyone have any idea?
Ex.
InitialDate | 3/29/2015
2ndDate | 4/28/2015<-- This is what's stored which is pre-iteration
3rdDate | 5/28/2015<-- This is what it's supposed to be after the iteration
so on and so forth....
Values pre-iteration
//Date stuff
String startdate = (String.valueOf(Acc._date));
DateTimeFormatter formatter = DateTimeFormat.forPattern("MM-dd-yyyy HH:mm:ss");
DateTime dt = formatter.parseDateTime(startdate);
DateTime startpoint = new DateTime(dt);
DateTime whendue = startpoint.plusDays(30);
DateTime foriteration = whendue;
String formattedDate = whendue.toString(formatter);
//Storing initial date
pay.setDateDue(formattedDate);
db.AddPayment(pay);
Actual iteration
while (i < j) {
//Operation for Date Calculation
DateTime ndt = foriteration.plusDays(30);
foriteration = ndt;
String newdate = ndt.toString(formatter);
//Adding values to PayTable
pay.setDateDue(newdate);
db.AddPayment(pay);
i++;
}
Finally found out what was wrong. Nothing. My roommate played a prank on me and just got back from his trip out of town and explained to me how he changed my getDateDue to execute a plusDays(30) to mimic my code so that when I called AddPayment which calls getDateDue it would look like it would work but in actuality would only add 30 days once to the startdate no matter what I did.
Summary
Roommate is an ass, nothing is wrong with my code. Sorry for this pointless post.
I am trying to make automatic attendance on my android phone [which is triggered by NFC]. I have tested the following Python code separately on PC:
from datetime import datetime
s1 = '09:40:00'
s2 = datetime.now().strftime('%H:%M:%S')
s3 = datetime.now().strftime('%I:%M:%S %p')
FMT = '%H:%M:%S'
tdelta = datetime.strptime(s2, FMT) - datetime.strptime(s1, FMT)
print ('I have arrived ['+str(tdelta)+']' 'HH:MM:SS'' late at ['+str(s3)+'].')
And following Android Code separately:
droid = android.Android
import android
number = "mycellnumber"
message = "Hello"
droid.smsSend(number, message.encode("utf-8"))
What I want is to merge these two codes and send the following as message(and in email body later):
('I have arrived ['+str(tdelta)+']' 'HH:MM:SS'' late at ['+str(s3)+'].')
I am able to merge the code and now it looks like this:
import android
import datetime
droid = android.Android()
s1= '09:40:00'
s2= datetime.datetime.now().strftime('%H:%M:%S')
s3= datetime.datetime.now().strftime('%I:%M:%S %p')
FMT = '%H:%M:%S'
tdelta = datetime.datetime.strptime(s2,FMT) - datetime.datetime.strptime(s1,FMT)
print ('I have arrived ['+str(tdelta)+']')
number = "XXXXXXXXXX"
message = str(tdelta)
droid.smsSend(number, message.encode("utf"))
I came across the most weird problem with dates on a Sony Xperia LT26i. A date format: "hh:mm:ss a" will print "01:00 p.m." and on most devices it prints "01:00 pm". Any clue why is this? It is messing my joda time as I cant parse times that come from the server.
JodaTime can parse the local am/pm-strings your device produces. What to do with different strings coming from server? Since you expect fortunately only the markers "am" or "pm" from server I suggest to use two specialized formatter objects using am/pm-literals for parsing. So that is the workaround:
static final DateTimeFormatter AM_PARSER = DateTimeFormat.forPattern("hh:mm:ss 'am'");
static final DateTimeFormatter PM_PARSER = DateTimeFormat.forPattern("hh:mm:ss 'pm'");
public static LocalTime parseServer(String input) {
if (input.endsWith("am")) {
return AM_PARSER.parseLocalTime(input);
} else {
LocalTime lt = PM_PARSER.parseLocalTime(input);
return lt.plusHours(12); // necessary because we parse pm only as literal
}
}
Explanation:
If you study the JodaTime-source code then you will find that am/pm-strings finally come from DateFormatSymbols.getInstance(locale).getAmPmStrings(). So the question arises why you have "p.m." instead of "pm" on Sony Xperia device. This leads to the question what is the data source of class DateFormatSymbols. This is dependent on the JVM-provider who manages such data in any resource directory (in your case dependent on your special Android configuration, in my case in resource bundle class sun.text.resources.FormatData). It is really different for every JVM (and Android is not even an official Java-VM).
After thinking a little bit I have come up with this solution
public static LocalTime localTimeParse(String date, DateTimeFormatter dateTimeFormatter) {
if(!StringUtils.hasText(date) || dateTimeFormatter == null)
return null;
LocalTime localTime = null;
try {
localTime = LocalTime.parse(date,dateTimeFormatter);
} catch(IllegalArgumentException exception) {
//This can happen on devices that have their time in the following format "01:00 p.m." insetad of "01:00 pm"
//Sony Xperia lT26i is one of them
String newDate = date.toLowerCase(Locale.getDefault()).contains("am") ? date.toLowerCase(Locale.getDefault()).replace("am", "a.m.") : date.toLowerCase(Locale.getDefault()).replace("pm", "p.m.");
localTime = LocalTime.parse(newDate,dateTimeFormatter);
}
return localTime;
}
This can be used like this:
DateTimeFormatter formatter = DateTimeFormat.forPattern("hh:mm a");
LocalTime localTime = DateUtils.localTimeParse("09:00 PM",formatter);
It works on Xperia a non Xperia
I want to get a Double with 3 decimalplaces. I do this:
String sAveragePrice;
Double dAveragePrice = holePrice/(allPrices.size()); // delivers 1.3210004
DecimalFormat threeZeroes = new DecimalFormat("#0.000");
sAveragePrice = threeZeroes.format(dAveragePrice); // delivers then 1,321
After formatting I dont get a 1.321 but 1,321. And the 1,321 throws a NumberformatException later. This is when it is thrown:
Double priceInt = Double.parseDouble(sAveragePrice); // throws NumberFormatException
The strange thing is, I have this code till 3 weeks and it didn't make any problem. But today when I have started my app again it gets problem with it. But I didn't have changed anything.
Can anybody help me? I also tried this:
NumberFormat format = NumberFormat.getNumberInstance();
format.setMinimumFractionDigits(3);
format.setMaximumFractionDigits(3);
sAveragePrice = format.format(dAveragePrice);
But it also delivers me a "," instead of a "." for double.
Try using a locale for you number format.
Number format = NumberFormat.getNumberInstance(Locale.ITALIAN);
Java SDK has a limited number of predefined locale settings, so for other locales (e.g., for Russian), you can use the following snippet:
Number format = NumberFormat.getNumberInstance(new Locale("ru", "RU"));
Number format = NumberFormat.getNumberInstance(new Locale("it", "IT")); // etc...
this sample code may help you...
Locale locale = Locale.getDefault();
// set Locale.US as default
Locale.setDefault(Locale.US);
DecimalFormat decimalFormat = new DecimalFormat("##.000");
double d = 14.5589634d;
String format = decimalFormat.format(d);
System.out.println(format);// prints 14.559
// back to default locale
Locale.setDefault(locale);
Have a look at this SO question
How to change the decimal separator of DecimalFormat from comma to dot/point?
Basically your output will be Locale specific, so if you have a Locale of Frame then it will be different to a Locale of the US.
try
NumberFormat format = NumberFormat.getNumberInstance(Locale.US);
Use this type of formatting
use # instead of 0. It is the correct format to declare your pattern
String sAveragePrice;
Double dAveragePrice = holePrice/(allPrices.size());
DecimalFormat threeZeroes = new DecimalFormat("#.###");
sAveragePrice = threeZeroes.format(dAveragePrice);
Hope it will help you