Calcola la differenza di orario client-server nel server Borland Starteam 8
Domanda
problema . Ho bisogno di un modo per trovare l'ora del server Starteam tramite Starteam Java SDK 8.0. La versione del server è 8.0.172, quindi il metodo Server.getCurrentTime()
non è disponibile poiché è stato aggiunto solo nella versione 9.0 del server.
Motivazione . La mia applicazione deve utilizzare le visualizzazioni in date specifiche. Quindi, se c'è qualche differenza nel tempo di sistema tra client (dove l'app è in esecuzione) e server, le visualizzazioni ottenute non sono accurate. Nel peggiore dei casi la data richiesta dal client è in futuro per il server, quindi l'operazione si traduce in un'eccezione.
Soluzione
Dopo alcune indagini non ho trovato alcuna soluzione più pulita dell'uso di un oggetto temporaneo. La mia app richiede l'ora di creazione dell'articolo e la confronta con l'ora locale. Ecco il metodo che uso per ottenere l'ora del server:
public Date getCurrentServerTime() {
Folder rootFolder = project.getDefaultView().getRootFolder();
Topic newItem = (Topic) Item.createItem(project.getTypeNames().TOPIC, rootFolder);
newItem.update();
newItem.remove();
newItem.update();
return newItem.getCreatedTime().createDate();
}
Altri suggerimenti
Se il tuo server StarTeam si trova su una finestra di Windows e il tuo codice verrà eseguito su una finestra di Windows, potresti sborsare ed eseguire il comando NET time per recuperare il tempo su quella macchina e poi confrontare all'ora locale.
net time \\my_starteam_server_machine_name
che dovrebbe restituire:
"Current time at \\my_starteam_server_machine_name is 10/28/2008 2:19 PM"
"The command completed successfully."
Dovevamo trovare un modo per trovare l'ora del server da utilizzare con CodeCollab. Ecco un esempio (longish) di codice C # su come farlo senza creare un file temporaneo. La risoluzione è di 1 secondo.
static void Main(string[] args)
{
// ServerTime replacement for pre-2006 StarTeam servers.
// Picks a date in the future.
// Gets a view, sets the configuration to the date, and tries to get a property from the root folder.
// If it cannot retrieve the property, the date is too far in the future. Roll back the date to an earlier time.
DateTime StartTime = DateTime.Now;
Server s = new Server("serverAddress", 49201);
s.LogOn("User", "Password");
// Getting a view - doesn't matter which, as long as it is not deleted.
Project p = s.Projects[0];
View v = p.AccessibleViews[0]; // AccessibleViews saves checking permissions.
// Timestep to use when searching. One hour is fairly quick for resolution.
TimeSpan deltaTime = new TimeSpan(1, 0, 0);
deltaTime = new TimeSpan(24 * 365, 0, 0);
// Invalid calls return faster - start a ways in the future.
TimeSpan offset = new TimeSpan(24, 0, 0);
// Times before the view was created are invalid.
DateTime minTime = v.CreatedTime;
DateTime localTime = DateTime.Now;
if (localTime < minTime)
{
System.Console.WriteLine("Current time is older than view creation time: " + minTime);
// If the dates are so dissimilar that the current date is before the creation date,
// it is probably a good idea to use a bigger delta.
deltaTime = new TimeSpan(24 * 365, 0, 0);
// Set the offset to the minimum time and work up from there.
offset = minTime - localTime;
}
// Storage for calculated date.
DateTime testTime;
// Larger divisors converge quicker, but might take longer depending on offset.
const float stepDivisor = 10.0f;
bool foundValid = false;
while (true)
{
localTime = DateTime.Now;
testTime = localTime.Add(offset);
ViewConfiguration vc = ViewConfiguration.CreateFromTime(testTime);
View tempView = new View(v, vc);
System.Console.Write("Testing " + testTime + " (Offset " + (int)offset.TotalSeconds + ") (Delta " + deltaTime.TotalSeconds + "): ");
// Unfortunately, there is no isValid operation. Attempting to
// read a property from an invalid date configuration will
// throw an exception.
// An alternate to this would be proferred.
bool valid = true;
try
{
string testname = tempView.RootFolder.Name;
}
catch (ServerException)
{
System.Console.WriteLine(" InValid");
valid = false;
}
if (valid)
{
System.Console.WriteLine(" Valid");
// If the last check was invalid, the current check is valid, and
// If the change is this small, the time is very close to the server time.
if (foundValid == false && deltaTime.TotalSeconds <= 1)
{
break;
}
foundValid = true;
offset = offset.Add(deltaTime);
}
else
{
offset = offset.Subtract(deltaTime);
// Once a valid time is found, start reducing the timestep.
if (foundValid)
{
foundValid = false;
deltaTime = new TimeSpan(0,0,Math.Max((int)(deltaTime.TotalSeconds / stepDivisor), 1));
}
}
}
System.Console.WriteLine("Run time: " + (DateTime.Now - StartTime).TotalSeconds + " seconds.");
System.Console.WriteLine("The local time is " + localTime);
System.Console.WriteLine("The server time is " + testTime);
System.Console.WriteLine("The server time is offset from the local time by " + offset.TotalSeconds + " seconds.");
}
Output:
Testing 4/9/2009 3:05:40 PM (Offset 86400) (Delta 31536000): InValid
Testing 4/9/2008 3:05:40 PM (Offset -31449600) (Delta 31536000): Valid
...
Testing 4/8/2009 10:05:41 PM (Offset 25200) (Delta 3): InValid
Testing 4/8/2009 10:05:38 PM (Offset 25197) (Delta 1): Valid
Run time: 9.0933426 seconds.
The local time is 4/8/2009 3:05:41 PM
The server time is 4/8/2009 10:05:38 PM
The server time is offset from the local time by 25197 seconds.
<stab_in_the_dark>
Non ho familiarità con quell'SDK ma dall'osservazione dell'API se il server si trova in un fuso orario noto, perché non creare e un oggetto OLEDate la cui data sarà l'ora del client ruotata in modo appropriato in base al fuso orario del server?
</stab_in_the_dark>