Convert timestamp to a specified timezone offset - timezone

How can I convert a long timestamp, e.g. 2556072000000L, to a String in a specified timezone offset, e.g. +08:30? I looked into Joda methods but didn't find a solution.
Similarly, how can I convert a String timestamp, e.g. 2050-12-31T04:00:00Z, to a String in a specified timezone offset, e.g. +08:30?
2050-12-31T12:30:00+08:30 in the specified offset is expected.
Parsing +08:30 into three parts: +, hour offset (8) and minute offset (30), add the offset to the timestamp or dateTime could be a solution. However, I'm wondering whether there's already a solution so that I needn't reinvent wheels?
/*
* timestamp: 2556072000000L (2050-12-31T04:00:00Z)
* offset: +08:30
* return: 2050-12-31T12:30:00+08:30
*/
String toOffset(long timestamp, String offset);
/*
* dateTime: 2050-12-31T04:00:00Z
* offset: +08:30
* return: 2050-12-31T12:30:00+08:30
*/
String toOffset(String dateTime, String offset);

Reading this article, I got the answer to my question. Here it is:
import java.time.ZoneOffset;
/*
* timestamp: 2556072000000L (2050-12-31T04:00:00Z)
* offset: +08:30
* return: 2050-12-31T12:30:00+08:30
*/
public String toOffset(long timestamp, String offset); { // +08:30
DateTime time = new DateTime(timestamp + getOffsetMillis(offset));
time = time.withZone(DateTimeZone.forID(DateTimeZone.UTC.getID())); // 2050-12-31T12:30:00Z
DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss");
String dateStr = time.toString(formatter); // 2050-12-31T12:30:00
return dateStr + offset; // 2050-12-31T12:30:00+08:30
}
public long getOffsetMillis(String offset) { // +08:30
ZoneOffset zoneOffSet = ZoneOffset.of(offset);
return zoneOffSet.getTotalSeconds() * 1000; // (8 * 60 * 60 + 30 * 60) * 1000
}
Please note that the timezone offset must be in the inclusive range of [-18:00, +18:00]. Below is quoted from JDK document
In 2008, time-zone offsets around the world extended from -12:00 to
+14:00. To prevent any problems with that range being extended, yet still provide validation, the range of offsets is restricted to -18:00
to 18:00 inclusive.
If you look at the Joda timezone table, you will find that offsets for all the timezones are in the range of [-12:00, +14:00].

Related

How to fix Error 130 on MT4 Expert Advisor Short trades?

I am trying to get this code to trade short. It trades long but give MT4 Error 130 invalid stop loss and is not going short. What do I change so this code goes short?
Code:
string symbol = "EURUSD"; // symbol
double volume = .01; // volume
int slippage = 0; // slippage
double pricelong = Ask; // price
string cmdlong = "OP_BUYLIMIT"; // operation
double stoplosslong = Ask - .0005; // stop loss
double takeprofitlong = Bid + .0005; // take profit
string commentlong="Long"; // comment
color arrow_color_long=Green; // color
double priceshort = Bid; // price
string cmdshort = "OP_SELLLIMIT"; // operation
double stoplossshort = 25; // stop loss
double takeprofitshort = 50; // take profit
string commentshort="Short"; // comment
color arrow_color_short=Red; // color
int magic=0; // magic number
datetime expiration=0; // pending order expiration
orderresults = OrderSend(symbol, cmdshort , volume, priceshort, slippage, stoplossshort, takeprofitshort, commentshort, magic, expiration, arrow_color_short);

How to convert send order from mql4 to mql5

Below is the method I'm using to place an order after three minutes if it doesn't go through. I've converted the larger part of it from mql4 to mql5. It's just the commented part that I'm not sure how I'll change to mql5 since in mql5 send orders return bool's and not int's. I would be glad if I could get help with fixing this remaining part.
void MakeOrders()
{
static datetime lastTime = 0;
datetime currTime = iTime(Symbol(),PERIOD_M3,0);
if (currTime>lastTime)
{
for (int i=ObjectsTotal(0, 0, -1)-1; i>=0; i--)
{
string name = ObjectName(0, i, 0, -1);
if (ObjectGetString(0, name, OBJPROP_NAME, 0)==OBJ_RECTANGLE && ObjectGetString(0,name,OBJPROP_TEXT)=="")
{
double entryPrice=ObjectGetDouble(0,name,OBJPROP_PRICE,1)-3*_Point;
double stopLoss=ObjectGetDouble(0,name,OBJPROP_PRICE,2);
double slDist=fabs(entryPrice-stopLoss);
double dTakeProfit=entryPrice-2*slDist;
MqlTradeRequest request={0};
MqlTradeResult result={0};
//--- parameters of request
request.action =TRADE_ACTION_DEAL; // type of trade operation
request.symbol =Symbol(); // symbol
request.volume =lotSize; // volume of 0.1 lot
request.type =ORDER_TYPE_BUY_LIMIT; // order type
request.price = entryPrice; // price for opening
//request.deviation=5; // allowed deviation from the price
request.magic =magicnumber; // MagicNumber of the order
request.tp = dTakeProfit;
request.sl = stopLoss;
//--- send the request
if(!OrderSend(request,result))
PrintFormat("OrderSend error %d",GetLastError());
/*
int ticketSell = OrderSend(Symbol(),OP_SELLLIMIT,lotSize, entryPrice,0,stopLoss,dTakeProfit,"SellOrder",magicnumber,0,Red);
if (ticketSell>0)
{
ObjectSetText(name,string(ticketSell));
i = ObjectsTotal()-1; // rather than continuing the 'for' loop, we must restart because arrows (ie new objects) were created.
}
*/
}
}
lastTime = currTime;
}
}
if(result.retcode==10009 || result.order>0)
ObjectSetText(name,string(result.order));

Objective C: Getting NSTimeInterval by a formatted String

I want to make an app which is able to calculate the time at work (and other things like flexitime).
Getting a String of a flexitime (which is a NSTimeInterval) by a specific format is really easy and I have written a method for this with the possibility of adding a specific format:
+ (NSString *)stringForTimeInterval: (NSTimeInterval) interval withFormat: (NSString *)format
This method returns #"25:00" for a flexitime of 90000.0 and #"-25:00" for -90000.0. format for both examples is #"HH:mm".
The format is a string which looks like #"HH:mm". "HH" are hours (could be any positive or negative integer but will normally be between bounds of -300 and 300) and "mm" are minutes (0 - 59, digits 0 - 9 get a leading zero).
Now I want to write a method to get back a NSTimeInterval of a string formatted with a known format.
+ (NSTimeInterval)timeIntervalForString: (NSString *)timeString withFormat: (NSString *)format
I really do not know how to do this. I can not use a normal NSDateFormatter because a flexitime could be more than 23:59 and less than 00:00.
There also has to be a TimeFormat because I want to give the users the possibility of easily switching their format.
I also want to have the possibility of adding a new timeFormat in a few seconds (actually I just have to add a new NSString to an NSArray to add a new format in the whole app).
I also tried regex but I found no way how to solve it with.
Does anybody know how I could solve this?
Edit:
This is my method for getting a string of hours and minutes with a specific format:
+ (NSString *)stringForTimeInterval: (NSTimeInterval) interval withFormat: (NSString *)format
{
// minutes are never negative!
int minutes = abs((int)interval / 60 % 60);
int hours = (int)interval / 3600;
// replacing 'HH' and 'mm'
NSString *time = [[format stringByReplacingOccurrencesOfString:#"HH" withString:[NSString stringWithFormat:#"%0.2d", hours]] stringByReplacingOccurrencesOfString:#"mm" withString:[NSString stringWithFormat:#"%0.2d", minutes]];
return time;
}

Odd atoi(char *) issue

I'm experiencing a very odd issue with atoi(char *). I'm trying to convert a char into it's numerical representation (I know that it is a number), which works perfectly fine 98.04% of the time, but it will give me a random value the other 1.96% of the time.
Here is the code I am using to test it:
int increment = 0, repetitions = 10000000;
for(int i = 0; i < repetitions; i++)
{
char randomNumber = (char)rand()%10 + 48;
int firstAtoi = atoi(&randomNumber);
int secondAtoi = atoi(&randomNumber);
if(firstAtoi != secondAtoi)NSLog(#"First: %d - Second: %d", firstAtoi, secondAtoi);
if(firstAtoi > 9 || firstAtoi < 0)
{
increment++;
NSLog(#"First Atoi: %d", firstAtoi);
}
}
NSLog(#"Ratio Percentage: %.2f", 100.0f * (float)increment/(float)repetitions);
I'm using the GNU99 C Language Dialect in XCode 4.6.1. The first if (for when the first number does not equal the second) never logs, so the two atoi's return the same result every time, however, the results are different every time. The "incorrect results" seemingly range from -1000 up to 10000. I haven't seen any above 9999 or any below -999.
Please let me know what I am doing wrong.
EDIT:
I have now changed the character design to:
char numberChar = (char)rand()%10 + 48;
char randomNumber[2];
randomNumber[0] = numberChar;
randomNumber[1] = 0;
However, I am using:
MAX(MIN((int)(myCharacter - '0'), 9), 0)
to get the integer value.
I really appreciate all of the answers!
atoi expects a string. You have not given it a string, you have given it a single char. A string is defined as some number of characters ended by the null character. You are invoking UB.
From the docs:
If str does not point to a valid C-string, or if the converted value would be out of the range of values representable by an int, it causes undefined behavior.
Want to "convert" a character to its integral representation? Don't overcomplicate things;
int x = some_char;
A char is an integer already, not a string. Don't think of a single char as text.
If I'm not mistaken, atoi expects a null-terminated string (see the documentation here).
You're passing in a single stack-based value, which does not have to be null-terminated. I'm extremely surprised it's even getting it right: it could be reading off hundreds of garbage numbers into eternity, if it never finds a null-terminator. If you just want to get the number of a single char (as in, the numeric value of the char's human-readable representation), why don't you just do int numeric = randomNumber - 48 ?

Convert int val to format "HH:MM:SS" using JDK1.4

What is the most efficient method of converting an int val to its string counterpart in this format - "HH:MM:SS"
10 becomes 00:00:10
70 becomes 00:01:10
3610 becomes 01:00:10
I need this to be JDK1.4 compliant.
What I've come up with is a series of if statements and then constructing a string based on the current int val. This is not very efficient. Is there a better way?
Instead of a heap of code, how about just one line?
String time = new SimpleDateFormat("HH:mm:ss")
{{setTimeZone(TimeZone.getTimeZone("UTC"));}}.format(new Date(3610 * 1000)); // "01:00:10"
p.s. I never fails to amaze me just how much code some people write to do the simplest of things
The timezone is set to UTC, because SimpleDateFormat uses your locale to format the date. For example my timezone is GMT+10 and if I format new Date(0), the time part is "10:00:00".
For those who don't recognise that odd syntax where the timezone is being set, it's an anonymous class with an "instance block", which gets executed on construction, after the constructor has finished.
You need to clarify your definition of "efficient". To me efficient is "doesn't requiring to reinvent the wheel myself". Which means using libraries (yes, java.util.Calendar is quite outdated, but still better than coding it yourself):
int yourIntInSeconds = 3610;
Calendar dayStart = Calendar.getInstance();
dayStart.set(Calendar.HOUR_OF_DAY, 0);
dayStart.set(Calendar.MINUTE, 0);
dayStart.set(Calendar.SECOND, 0);
// also reset subsecond values if plan to display those
dayStart.add(Calendar.SECOND, yourIntInSeconds);
System.out.println(
new SimpleDateFormat("HH:mm:ss").format(
new Date(dayStart.getTimeInMillis())
)
);
All of Calendar, Date and SimpleDateFormat are compatible with JDK 1.4.
This is what I do:
private static final String LONG_DURATION_FMT = "%d:%02d:%02d";
private static final String SHORT_DURATION_FMT = "%d:%02d";
public static String formatSecondsAsDuration(long seconds) {
final long h = seconds / 3600;
final long remainder = seconds % 3600;
final long m = remainder / 60;
final long s = remainder % 60;
if (h > 0) {
return String.format(LONG_DURATION_FMT, h, m, s);
} else {
return String.format(SHORT_DURATION_FMT, m, s);
}
}
But using a StringBuffer instead of String.format could be faster. Just try it.
How about this (I made it in my last project):
public static String formatTime(long totalSeconds)
{
int hours, minutes, remainder, totalSecondsNoFraction;
double seconds;
// Calculating hours, minutes and seconds
String s = Double.toString(totalSeconds);
String [] arr = s.split("\\.");
totalSecondsNoFraction = Integer.parseInt(arr[0]);
hours = totalSecondsNoFraction / 3600;
remainder = totalSecondsNoFraction % 3600;
minutes = remainder / 60;
seconds = remainder % 60;
if(arr[1].contains("E")) seconds = Double.parseDouble("." + arr[1]);
else seconds += Double.parseDouble("." + arr[1]);
// Formatting the string that conatins hours, minutes and seconds
StringBuilder result = new StringBuilder(".");
String sep = "", nextSep = " and ";
if(seconds > 0)
{
result.insert(0, " seconds").insert(0, seconds);
sep = nextSep;
nextSep = ", ";
}
if(minutes > 0)
{
if(minutes > 1) result.insert(0, sep).insert(0, " minutes").insert(0, minutes);
else result.insert(0, sep).insert(0, " minute").insert(0, minutes);
sep = nextSep;
nextSep = ", ";
}
if(hours > 0)
{
if(hours > 1) result.insert(0, sep).insert(0, " hours").insert(0, hours);
else result.insert(0, sep).insert(0, " hour").insert(0, hours);
}
return result.toString();
}

Resources