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();
}
Related
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 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].
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));
I'm using Tweetsharp library to display the latest 5 tweets posted by a user. I've created an app at dev/twitter and got the required tokens. I want to show the time lapsed since the tweet was posted. But the "tweet.CreatedDate" method from the Tweetsharp library is provides a time 5-6 hrs before the time of tweeting.
public DataSet GenerateTweetDataSet()
{
string time = "";
int hrs = 0, mins = 0;
int days = 0;
TwitterService service = new TwitterService(ConsumerKey, ConsumerSecret);
service.AuthenticateWith(AccessToken, AccessTokenSecret);
ListTweetsOnUserTimelineOptions tweetoptions = new ListTweetsOnUserTimelineOptions();
tweetoptions.Count = 5;
tweetoptions.ScreenName = _twitter.ScreenName;
var tweets = service.ListTweetsOnUserTimeline(tweetoptions);
DataTable TweetsTable = new DataTable();
TweetsTable.Columns.Add("Text");
TweetsTable.Columns.Add("DateTime");
TweetsTable.Columns.Add("Id");
if (tweets != null)
foreach (var tweet in tweets)
{
string UserName = tweet.User.ScreenName;
string TweetText = tweet.Text;
DateTime tweetDate = tweet.CreatedDate;
DateTime currentDate = DateTime.Now;
time = (currentDate - tweetDate).Days.ToString();
TimeSpan t1 = currentDate.Subtract(tweetDate);
mins = (Int32)t1.TotalMinutes;
hrs = (Int32)t1.TotalHours;
days = (Int32)t1.TotalDays;
if (mins < 60)
{
time = mins + " mins ago";
}
else if (mins > 60 && hrs <= 24)
{
time = hrs + " hours ago";
}
else if (hrs > 24 && days < 365)
{
time = days + " days ago";
}
else if (days > 365)
{
time = "over a year ago";
}
long id = tweet.Id;
TweetsTable.Rows.Add(TweetText, time, id);
}
DataSet ds = new DataSet();
ds.Tables.Add(TweetsTable);
return ds;
}
Can someone please point where I'm going wrong or how to fix this issue.
If not then, is there a better/simpler way to get the tweets? Any sample code without using any API library?
Any help will be appreciated.
Literal litAuthor = (Literal)e.Item.FindControl("litAuthor");
Literal litTime = (Literal)e.Item.FindControl("litTime");
HyperLink btnTwitter = (HyperLink)e.Item.FindControl("btnTwitter");
TwitterStatus twitterStatus = (TwitterStatus)e.Item.DataItem;
if (litAuthor != null)
{
if (twitterStatus != null)
{
TimeSpan diff = DateTime.Now - twitterStatus.CreatedDate;
if (diff.Days > 0)
{
litTime.Text = twitterStatus.CreatedDate.ToString("dd MMM yyyy");
}
else if (diff.Hours < 24)
{
litTime.Text = diff.Hours.ToString() + "h";
}
else
{
litTime.Text = diff.Minutes.ToString() + "m";
}
litAuthor.Text = twitterStatus.Author.ScreenName;
btnTwitter.Text = twitterStatus.Text;
btnTwitter.NavigateUrl = "http://twitter.com/" + twitterStatus.User.ScreenName + "/statuses/" + twitterStatus.IdStr;
}
}
private static long CalculateScore(byte chances, long millisec) { int score; byte num1 = chances++; byte num2 = (byte)10; byte num3 = (byte)10; switch (Program.currLevelIndex) { case (byte)7: num2 = (byte)10; break; case (byte)11: num2 = (byte)20; break; case (byte)15: num2 = (byte)40; break; }
if ((int)chances >= 1 && (int)chances <= 3)
num1 = (byte)40;
else if ((int)chances >= 4 && (int)chances <= 6)
num1 = (byte)20;
else if ((int)chances > 7)
num1 = (byte)10;
if (millisec > 480000L)
num3 = (byte)10;
else if (millisec >= 240000L && millisec <= 480000L)
num3 = (byte)20;
else if (millisec < 240000L)
num3 = (byte)40;
try
{
score = Convert.ToInt32((int)num2 * (int)num1 * (int)num3);
}
catch
{
score=0;
}
Console.SetCursorPosition(Program.x, Program.y);
Console.Write("Your Score was: " + score);
}`
The error is CalculateScore & I can't find the mistake. this is a method is to work ou Help is nedeed.
private static long CalculateScore expects a return value of type long, but your method does not return anything.
Add the following to the end of the method.
return score;
And you might want to change the return type to int or the score variable to long
private static int CalculateScore(byte chances, long millisec)
{
int score;
byte num1;
Or
private static long CalculateScore(byte chances, long millisec)
{
long score;
byte num1;
You specified that the function will return a value of type long, but there is no return statement returning a value at the end of the function
You need to add
return score;
as score is the result of the calculation