I am parsing several documments with the field Duration. But in the differents files, it is in differnt formats, ex:
"Duration": "00:43"
"Duration": "113.046"
"Duration": "21.55 s"
I want to parse all of them to the format "Duration": "113.046", how could I check before any parsing in wich format it is??
Some conditions before this piece of code, because this is not right for all of them:
Long duration;
DateFormat sdf = new SimpleDateFormat("hh:mm:ss");
try {
Date durationD = sdf.parse(totalDuration);
Date zeroSec = sdf.parse("00:00:00");
duration = durationD.getTime() - zeroSec.getTime();
} catch (Exception e) {
duration = Long.parseLong(totalDuration);
}
Thanks in advance
You could match the pattern with help of regex and then format accordingly. Here's a kickoff example:
Map<Pattern, DateFormat> dateFormatPatterns = new HashMap<Pattern, DateFormat>();
dateFormatPatterns.put(Pattern.compile("\\d{1,2}:\\d{2}"), new SimpleDateFormat("H:m"));
dateFormatPatterns.put(Pattern.compile("\\d{1,3}\\.\\d{3}"), new SimpleDateFormat("s.S"));
dateFormatPatterns.put(Pattern.compile("\\d{1,2}\\.\\d{2} s"), new SimpleDateFormat("s.S 's'"));
String[] strings = { "00:43", "113.046", "21.55 s" };
DateFormat finalFormat = new SimpleDateFormat("HH:mm:ss");
for (String string : strings) {
for (Pattern pattern : dateFormatPatterns.keySet()) {
if (pattern.matcher(string).matches()) {
Date date = dateFormatPatterns.get(pattern).parse(string);
String formattedTime = finalFormat.format(date);
System.out.println(formattedTime);
break;
}
}
}
This yields here
00:43:00
00:01:53
00:00:21
If these are all your known input formats, then convert your input to your expected date format.
Just string-replace all : with . and remove s.
Do not forget to strip the spaces, too. By the way, "113.046" seems a bit odd date format to me - if I were in your shoes, I would have used some of the standard date time formats and convert the irregular ones.
My solution, not smart at all:
long DurationFixer(String duration){
long durationLong = 0;
if(duration.contains(":")){
DateFormat sdf = new SimpleDateFormat("mm:ss");
try {
Date durationD = sdf.parse(duration);
Date zeroSec = sdf.parse("00:00:00");
durationLong = durationD.getTime() - zeroSec.getTime();
} catch (Exception e) {
durationLong = (Long.parseLong(duration))/1000;
}
}
else{
String r = "";
if(duration.contains("s")){
for (int i = 0; i < duration.length()-2; i ++) {
if ((duration.charAt(i) == '.'))
break;
else
r += duration.charAt(i);
}
}
durationLong = Long.valueOf(r);
}
return durationLong;
}
If someone could find a better solution, please, tell me.
Thanks everybody!
Related
how to use java in xslt and avoid below errors:
Cannot find a 1-argument function named
{java:com.poc.XSDDateTimeFormatter}toXSD(). Reflexive calls to Java
methods are not available under Saxon-HE and Cannot find a 2-argument
function named
{urn:java:com.poc.NLDataUnitTestTimeCalc}computeTestTime(). Reflexive
calls to Java methods are not available under Saxon-HE
computeTestTime method of NLDataUnitTestTimeCalc class
public static long computeTestTime( String startDateStr, String endDateStr) {
long testTime= 0;
long longStartDate= 0;
long longEndDate= 0;
for( String format: formats) {
try {
SimpleDateFormat formatter = new SimpleDateFormat(format);
Date startdate = formatter.parse(startDateStr);
Date enddate = formatter.parse(endDateStr);
longStartDate=startdate.getTime();
longEndDate=enddate.getTime();
testTime = (Math.abs(longEndDate-longStartDate)/1000);
break;
}
catch (ParseException ex) {
//ignore
}
}
return testTime;
}
toXSD method of XSDDateTimeFormatter class
public static String toXSD( String dateStr) {
for( String format: formats) {
try {
Date date = new SimpleDateFormat( format).parse( dateStr);
String xsd = new SimpleDateFormat( XSDdateTimeFormat).format( date);
//special case for xsd:dateTime timezone format
return
xsd.substring(0, xsd.length() - 2) +
':' +
xsd.substring(xsd.length() - 2);
} catch (ParseException ex) {
//ignore
}
}
return dateStr; }
xslt
<xsl:template match="/Event">
<bus:Timestamp>
<xsl:value-of xmlns:XSDDateTimeFormatter="java:com.amd.pde.integration.XSDDateTimeFormatter"
select="XSDDateTimeFormatter:toXSD( //TimeStamp)"
/>
</bus:Timestamp>
sample xml
<Event>
<Message>BEGINEXECUTION</Message>
<TimeStamp>20080111000419146</TimeStamp>
<EquipmentID>stack</EquipmentID>
</Event>
As the error message says, you use Saxon-HE, but extension functions in Java are only supported by Saxon-PE and Saxon-EE. The Saxon-Docs mention this explicitly.
I guess you have two options
Buy Saxon-PE or Saxon-EE
Implement your functions in XSL
I am running below command manager procedure in Microstrategy but it does not convert the string into date, tried lot of options. Can someone please assist?
*********** PROCEDURE***************************************
String sQuery = "LIST ALL SUBSCRIPTIONS FOR SCHEDULE \"" + sScheduleName + "\" FOR PROJECT \"" + projectName + "\";";
ResultSet oSubs=executeCapture(sQuery);
oSubs.moveFirst();
while(!oSubs.isEof()){
String sSubsName = oSubs.getFieldValueString(DisplayPropertyEnum.GUID);
ResultSet RecList = executeCapture("LIST ALL PROPERTIES FOR SUBSCRIPTION GUID " +sSubsName+ " FOR PROJECT \"projectname\";");
RecList.moveFirst();
while(!RecList.isEof()){
ResultSet oResultSetSubProps = (ResultSet)RecList.getResultCell(SUBSCRIPTION_RESULT_SET).getValue();
oResultSetSubProps.moveFirst();
while(!oResultSetSubProps.isEof())
{
String d1 = oResultSetSubProps.getFieldValueString(DisplayPropertyEnum.EXPIRATIONDATE);
// the below few lines in red return nothing, its unable to convert to Date as it is unable to recognize the Expiration date in the String format.
java.text.SimpleDateFormat formatter = new java.text.SimpleDateFormat("M/dd/yyyy");
String dateInString = d1;
Date date = formatter.parse(dateInString);
printOut(formatter.format(date));
oResultSetSubProps.moveNext();
}
RecList.moveNext();
}
oSubs.moveNext();
}
This worked for me. The string was neither empty, nor null and no even blank but it would still not parse it so i had to use the length of the string.
java.text.DateFormat formatter = new java.text.SimpleDateFormat("M/d/yyyy",Locale.US);
String dateInString = d1;
if(d1.trim().length()>0)
{
Date date = formatter.parse(dateInString);
if(todaydate.compareTo(date)>0)
{
printOut(name+";"+formatter.format(date));
}
}
if(d1.contains("/"))
{
Date EDate=new Date(d1);
Date today= new Date();
if(d1.compareTo(today)<0)
{
printOut("Expired");
}
}
else
{
printOut("Active");
}
//blank or null values can be handled in Else condition instead.. Hope it helps..
I have below method in which different date patterns have been handled
below is the method in which different date formats have been handled now
now for the particulat format YYYY-MM-dd i don't want it to go for the check where we are prefixing 20 before in code please advise how can i skip that part lets say if the date pattern is YYYY-MM-dd then avoid the logic of prefixing 20 in front of year
below is my code
public java.util.Date extractDate(String dateStr, String dateType) {
String[] datePatternsOfUk = { "d-M-yy", "d-M-yyyy", "d/M/yy", "d/M/yyyy", "yyyy-MM-dd","dd-MM-yy", "dd-MMM-yy","dd-MMM-yyyy","dd-MM-yyyy",
"dd/MM/yy","dd/MMM/yy","dd/MMM/yyyy"};
String[] datePatternsOfUs = { "M-d-yy","MM-dd-yy","M/d/yy","MM/dd/yy", "MM/dd/yy", "MMM-dd-yy",
"MMM/dd/yy", "MMM-dd-yyyy", "MM-dd-yyyy", "MMM/dd/yyyy",
"MM/dd/yyyy" };
java.util.Date date = null;
String[] datePatterns = datePatternsOfUk;
if (dateType.equals("US")) {
datePatterns = datePatternsOfUs;
} else if (dateType.equals("UK")) {
datePatterns = datePatternsOfUk;
}
///******code should not go in this check where date pattern is YYYY-MM-dd
int p = dateStr.lastIndexOf("/");
if (p == -1) {
p = dateStr.lastIndexOf("-");
}
String firstSubstring = dateStr.substring(0, p + 1);
String secondSubstring = dateStr.substring(p + 1);
if (p != -1 && secondSubstring.length() <= 2) {
secondSubstring = Integer.toString(2000 + Integer.parseInt(secondSubstring));
dateStr = firstSubstring + secondSubstring;
}
///****************************************//
try {
date = DateUtils.parseDate(dateStr, datePatterns);
} catch (ParseException ex) {
logger.error("##$$$$$### Error in invoice inside extractDate method : ##$$$$$$#### "
+ ErrorUtility.getStackTraceForException(ex));
}
return date;
}
You could avoid trying any inappropriate pattern by checking if the string "looks like" the pattern before parsing with the pattern.
The general way to do this is:
String datePattern = "yyyy-MM-dd"; // for example
String input;
if (input.matches(datePattern.replaceAll("\\w", "\\d"))) {
// the input looks like the pattern
// in this example "dddd-dd-dd" where "d" is any digit
// so go ahead and try the parse
}
You can enhance this logic to add:
if (input.matches("\\d\\d\\D.*")) {
// then it only has a two digit year, so add "20" to the front
}
if (!dateStr.equals("YYYY-MM-dd")) {
// code
}
I`m trying to build formatter in JodaTime to parse Period from strings like these:
year 1hour 90min
1year -60days 800min
1year +1months -1days +1hour -30min
I know I can build parser with PeriodFormatterBuilder in jodatime but with it I can`t parse first two examples
PeriodFormatter formatter = new PeriodFormatterBuilder()
.appendYears().appendSuffix("year", "years").appendSeparatorIfFieldsAfter(" ")
.appendMonths().appendSuffix("month", "months").appendSeparatorIfFieldsAfter(" ")
.appendDays().appendSuffix("day", "days").appendSeparatorIfFieldsAfter(" ")
.appendHours().appendSuffix("hour", "hours").appendSeparatorIfFieldsAfter(" ")
.appendMinutes().appendSuffix("min", "mins").appendSeparatorIfFieldsAfter(" ")
.appendSeconds().appendSuffix("sec", "secs")
.toFormatter();
Is there any way I can tell joda that tose fields are optional?
If you really wanna achieve this, you can do so by writing a custom parser. For this you will have to implement PeriodParser class and implement the parseInto() method.
#Override
public int parseInto(ReadWritablePeriod period, String periodStr,
int position, Locale locale) {
String tokens[] = periodStr.split(" ");
period.addYears(0);
period.addMonths(0);
period.addDays(0);
period.addHours(0);
period.addMinutes(0);
period.addSeconds(0);
for (String token : tokens) {
int count = 0;
if (token.contains("year")) {
String years = token.substring(0, token.indexOf("year"));
period.addYears(years.length() > 0 ? Integer.valueOf(years) : 0);
continue;
}
if (token.contains("hour")) {
period.addHours(Integer.valueOf(token.substring(0, token.indexOf("hour"))));
continue;
}
if (token.contains("min")) {
period.addMinutes(Integer.valueOf(token.substring(0, token.indexOf("min"))));
continue;
}
if (token.contains("months")) {
period.addMonths(Integer.valueOf(token.substring(0, token.indexOf("months"))));
continue;
}
if (token.contains("day")) {
period.addDays(Integer.valueOf(token.substring(0, token.indexOf("days"))));
continue;
}
}
return periodStr.length();
}
After that use the following code to create a formatter and parse the period.
PeriodFormatterBuilder builder = new PeriodFormatterBuilder();
PeriodFormatter formatter = builder.append(null, new MyParsePeriod()).toFormatter();
How to parse two different objects from the same json file knowing that parsing one of them block parsing the other, which means that i have to parse only one of them, this is my code:
try {
time = json1.getJSONObject(TAG_TIME);
String Time2 = time.toString();
deals = json1.getJSONObject(TAG_DEALS);
final String plusinfo = deals.getString(TAG_PLUS_INFO);
String title = deals.getString(TAG_TITLE);
Integer retail = deals.getInt(TAG_RETAIL);
String nretail = Integer.toString(retail);
Integer deal = deals.getInt(TAG_DEAL);
String ndeal = Integer.toString(deal);
String duration = deals.getString(TAG_DURATION);
String image = deals.getString(TAG_IMAGE_URL);
String participant = deals.getString(TAG_PARTICIPANT);
final String details = deals.getString(TAG_DETAILS);
final String name = deals.getString(TAG_ADVERTISER_NAME);
final String adress = deals.getString(TAG_ADVERTISER_ADDRESS);
final String phone = deals.getString(TAG_ADVERTISSER_PHONE);
/*String Time1 = deals.getString(TAG_DATE);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date1 = new GregorianCalendar(0,0,0).getTime();
Date date2 = new GregorianCalendar(0,0,0).getTime();
try {
date1 = sdf.parse(Time1);
date2 = sdf.parse(Time2);
} catch (ParseException e) {
e.printStackTrace();
}
final String precision = deals.getString(TAG_PRECISION);
JSONArray c = deals.getJSONArray(TAG_PRECISION);
ArrayList<String> arrays = new ArrayList<String>();
for(int i = 0; i < c.length(); i++){
precision = c.getString(i);
arrays.add(precision);
}
HashMap<String, String> map = new HashMap<String, String>();
map.put(TAG_TITLE, title);
map.put(TAG_RETAIL, nretail);
map.put(TAG_DEAL, ndeal);
map.put(TAG_DURATION, duration);
map.put(TAG_IMAGE_URL, image);
map.put(TAG_PARTICIPANT, participant);
map.put(TAG_SERVER_TIME, Time2);
otherdeals.add(map);
What do you mean it gets blocked? I dont see what the issue is with what you have posted. If you wish to parse two different JSON responses, either kick off two background threads (AsyncTask) or just parse them one after the other